diff --git a/.changeset/afraid-flies-try.md b/.changeset/afraid-flies-try.md deleted file mode 100644 index 15d2e3942c..0000000000 --- a/.changeset/afraid-flies-try.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-cost-insights': patch ---- - -Move cost-insights data specific API types (non react) into an @backstage/plugin-cost-insights-common -isomorphic package. This allows these types to be shared in any backend packages or other cost-insight -modules. diff --git a/.changeset/beige-carpets-double.md b/.changeset/beige-carpets-double.md deleted file mode 100644 index 98e0d8d69a..0000000000 --- a/.changeset/beige-carpets-double.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@backstage/plugin-code-coverage': minor ---- - -Cleaned up API exports. - -The `Router` export has been removed; users are expected to use `EntityCodeCoverageContent` instead. - -The `isPluginApplicableToEntity` helper has been deprecated, in favor of the `isCodeCoverageAvailable` helper. diff --git a/.changeset/beige-carpets-triple.md b/.changeset/beige-carpets-triple.md deleted file mode 100644 index 5eda26fb02..0000000000 --- a/.changeset/beige-carpets-triple.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-code-coverage-backend': minor ---- - -Cleaned up API exports. - -The `CodeCoverageApi` and `makeRouter` exports have been removed from the backend, since they were not meant to be exported in the first place. diff --git a/.changeset/beige-horses-scream.md b/.changeset/beige-horses-scream.md deleted file mode 100644 index 2034491108..0000000000 --- a/.changeset/beige-horses-scream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-github-pull-requests-board': patch ---- - -Fix bug on fetching teams repositories where were being filtered by type service unnecessarily diff --git a/.changeset/beige-kiwis-know.md b/.changeset/beige-kiwis-know.md deleted file mode 100644 index 696b9e81cb..0000000000 --- a/.changeset/beige-kiwis-know.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-plugin-api': minor ---- - -Introduced new package for creating backend plugins using the new alpha backend plugin framework. -This package is still considered **EXPERIMENTAL** and things will change without warning. Do not use this for production. diff --git a/.changeset/beige-pumas-tap.md b/.changeset/beige-pumas-tap.md new file mode 100644 index 0000000000..8ed8aab1f4 --- /dev/null +++ b/.changeset/beige-pumas-tap.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +--- + +Add the option for a homepage when using the `github:publish` action diff --git a/.changeset/blue-monkeys-explain.md b/.changeset/blue-monkeys-explain.md deleted file mode 100644 index 69382ff11d..0000000000 --- a/.changeset/blue-monkeys-explain.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Adds the ability to define the Backstage app name using a `BACKSTAGE_APP_NAME` -environment variable when running `create-app`. diff --git a/.changeset/brave-badgers-pump.md b/.changeset/brave-badgers-pump.md deleted file mode 100644 index 18dea30990..0000000000 --- a/.changeset/brave-badgers-pump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Fixed bug where catalog metrics weren't being tracked. diff --git a/.changeset/breezy-poems-grab.md b/.changeset/breezy-poems-grab.md deleted file mode 100644 index ac250b9c7e..0000000000 --- a/.changeset/breezy-poems-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-tech-insights-backend': patch ---- - -TechInsightsBackend: Added missing 'scheduler' to code examples diff --git a/.changeset/breezy-seas-exist.md b/.changeset/breezy-seas-exist.md deleted file mode 100644 index 2b061f11a8..0000000000 --- a/.changeset/breezy-seas-exist.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -The template editor now shows the cause of request errors that happen during a dry-run. diff --git a/.changeset/breezy-spiders-eat.md b/.changeset/breezy-spiders-eat.md deleted file mode 100644 index d163fc365f..0000000000 --- a/.changeset/breezy-spiders-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Fix Error Code in Register Component DryRun diff --git a/.changeset/bright-balloons-hide.md b/.changeset/bright-balloons-hide.md deleted file mode 100644 index 5163e72dc1..0000000000 --- a/.changeset/bright-balloons-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Change BackstageIconLinkVertical style to use pallette instead of explicit color diff --git a/.changeset/calm-experts-buy.md b/.changeset/calm-experts-buy.md deleted file mode 100644 index d95844e298..0000000000 --- a/.changeset/calm-experts-buy.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-node': minor ---- - -Added local publishing target directory `config`: `techdocs.publisher.local.publishDirectory` diff --git a/.changeset/chilled-mirrors-grab.md b/.changeset/chilled-mirrors-grab.md deleted file mode 100644 index ecc95680e2..0000000000 --- a/.changeset/chilled-mirrors-grab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Fix parsing of S3 URLs for the default region. diff --git a/.changeset/clever-beans-turn.md b/.changeset/clever-beans-turn.md new file mode 100644 index 0000000000..69846a2516 --- /dev/null +++ b/.changeset/clever-beans-turn.md @@ -0,0 +1,8 @@ +--- +'@backstage/plugin-kafka': patch +'@backstage/plugin-kafka-backend': patch +'@backstage/plugin-lighthouse': patch +'@backstage/plugin-proxy-backend': patch +--- + +Minor API signatures cleanup diff --git a/.changeset/cold-coins-tickle.md b/.changeset/cold-coins-tickle.md deleted file mode 100644 index 301a9d0a84..0000000000 --- a/.changeset/cold-coins-tickle.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': minor ---- - -Added an option to be able to trigger refreshes on entities based on a prestored arbitrary key. - -The UrlReaderProcessor, FileReaderProcessor got updated to store the absolute URL of the catalog file as a refresh key. In the format of `:` -The PlaceholderProcessor got updated to store the resolverValues as refreshKeys for the entities. - -The custom resolvers will need to be updated to pass in a `CatalogProcessorEmit` function as parameter and they should be updated to emit their refresh processingResults. You can see the updated resolvers in the `PlaceholderProcessor.ts` - -```ts - // yamlPlaceholderResolver - ... - const { content, url } = await readTextLocation(params); - - params.emit(processingResult.refresh(`url:${url}`)); - ... -``` diff --git a/.changeset/cold-frogs-kiss.md b/.changeset/cold-frogs-kiss.md new file mode 100644 index 0000000000..7af9468ca1 --- /dev/null +++ b/.changeset/cold-frogs-kiss.md @@ -0,0 +1,16 @@ +--- +'@backstage/plugin-scaffolder-backend': minor +--- + +Fixed a bug in plugin-scaffolder-backend where it ignores the skip migration database options. + +To use this new implementation you need to create the instance of `DatabaseTaskStore` using the `PluginDatabaseManager` instead of `Knex`; + +``` +import { DatabaseManager, getRootLogger, loadBackendConfig } from '@backstage/backend-common'; +import { DatabaseTaskStore } from '@backstage/plugin-scaffolder-backend'; + +const config = await loadBackendConfig({ argv: process.argv, logger: getRootLogger() }); +const databaseManager = DatabaseManager.fromConfig(config, { migrations: { skip: true } }); +const databaseTaskStore = await DatabaseTaskStore.create(databaseManager); +``` diff --git a/.changeset/cool-toys-flow.md b/.changeset/cool-toys-flow.md deleted file mode 100644 index 799bf3ace4..0000000000 --- a/.changeset/cool-toys-flow.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': minor ---- - -Add `transformLinkUri` and `transformImageUri` to `MarkdownContent` diff --git a/.changeset/create-app-1656408352.md b/.changeset/create-app-1656408352.md deleted file mode 100644 index b50d431d4b..0000000000 --- a/.changeset/create-app-1656408352.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Bumped create-app version. diff --git a/.changeset/cuddly-comics-pump.md b/.changeset/cuddly-comics-pump.md deleted file mode 100644 index 6d224bd34c..0000000000 --- a/.changeset/cuddly-comics-pump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Fixed that adding more than one `allowedOwner` or `allowedRepo` in the template config will now still set the first value as default in the initial form state of `RepoUrlPicker`. diff --git a/.changeset/cuddly-flowers-provide.md b/.changeset/cuddly-flowers-provide.md deleted file mode 100644 index 729ac96cda..0000000000 --- a/.changeset/cuddly-flowers-provide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-fossa': patch ---- - -Allow configuration of base URL for Fossa links diff --git a/.changeset/curly-candles-battle.md b/.changeset/curly-candles-battle.md deleted file mode 100644 index 9a4d850fd1..0000000000 --- a/.changeset/curly-candles-battle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Bumped `codemirror` dependencies to `v6.0.0`. diff --git a/.changeset/curvy-weeks-matter.md b/.changeset/curvy-weeks-matter.md deleted file mode 100644 index a0a9c43076..0000000000 --- a/.changeset/curvy-weeks-matter.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/catalog-model': patch -'@backstage/core-components': patch -'@backstage/plugin-techdocs-react': patch ---- - -Updated JSDoc to be MDX compatible. diff --git a/.changeset/eight-spies-protect.md b/.changeset/eight-spies-protect.md new file mode 100644 index 0000000000..0011dece72 --- /dev/null +++ b/.changeset/eight-spies-protect.md @@ -0,0 +1,25 @@ +--- +'@backstage/plugin-azure-devops': patch +'@backstage/plugin-azure-devops-backend': patch +'@backstage/plugin-azure-devops-common': patch +'@backstage/plugin-cloudbuild': patch +'@backstage/plugin-explore': patch +'@backstage/plugin-fossa': patch +'@backstage/plugin-git-release-manager': patch +'@backstage/plugin-github-actions': patch +'@backstage/plugin-jenkins': patch +'@backstage/plugin-newrelic-dashboard': patch +'@backstage/plugin-pagerduty': patch +'@backstage/plugin-scaffolder': patch +'@backstage/plugin-search-backend-node': patch +'@backstage/plugin-sentry': patch +'@backstage/plugin-sonarqube': patch +'@backstage/plugin-tech-insights': patch +'@backstage/plugin-tech-insights-node': patch +'@backstage/plugin-techdocs': patch +'@backstage/plugin-techdocs-module-addons-contrib': patch +'@backstage/plugin-user-settings': patch +'@backstage/plugin-vault-backend': patch +--- + +Minor API signatures cleanup diff --git a/.changeset/eight-suits-fail.md b/.changeset/eight-suits-fail.md deleted file mode 100644 index 742154da91..0000000000 --- a/.changeset/eight-suits-fail.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-kubernetes-common': patch ---- - -Fixed the lack of `limitranges` as part of the Default Objects to fetch from the kubernetes api diff --git a/.changeset/eighty-comics-divide.md b/.changeset/eighty-comics-divide.md deleted file mode 100644 index c486c1fa33..0000000000 --- a/.changeset/eighty-comics-divide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-model': patch ---- - -Add shared annotations for Kubernetes clusters diff --git a/.changeset/eighty-windows-brush.md b/.changeset/eighty-windows-brush.md deleted file mode 100644 index 753b53fbb4..0000000000 --- a/.changeset/eighty-windows-brush.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-tech-insights-backend': minor ---- - -Allow FactRetrieverRegistry to be injected into buildTechInsightsContext so that we can override default registry implementation. diff --git a/.changeset/famous-forks-carry.md b/.changeset/famous-forks-carry.md deleted file mode 100644 index 0362d463cd..0000000000 --- a/.changeset/famous-forks-carry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Add allowArbitraryValues for to provide input validation. This makes it a better experience of users, as they can now expect the values they enter to correspond to a valid owner. This is set to the default behavior by default. diff --git a/.changeset/fifty-cars-compare.md b/.changeset/fifty-cars-compare.md deleted file mode 100644 index 86115a4b02..0000000000 --- a/.changeset/fifty-cars-compare.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@backstage/plugin-kubernetes': minor -'@backstage/plugin-kubernetes-backend': minor ---- - -Add `localKubectlProxy` cluster locator method to make local development simpler to setup. - -Consolidated no-op server side auth decorators. -The following Kubernetes auth decorators are now one class (`ServerSideKubernetesAuthProvider`): - -- `AwsKubernetesAuthProvider` -- `AzureKubernetesAuthProvider` -- `ServiceAccountKubernetesAuthProvider` diff --git a/.changeset/fifty-vans-drum.md b/.changeset/fifty-vans-drum.md deleted file mode 100644 index 6b1b920bb9..0000000000 --- a/.changeset/fifty-vans-drum.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-tech-radar': patch ---- - -Update tech-radar documentation on how to use an external json data source with dates. diff --git a/.changeset/five-carrots-pay.md b/.changeset/five-carrots-pay.md new file mode 100644 index 0000000000..60fa91c163 --- /dev/null +++ b/.changeset/five-carrots-pay.md @@ -0,0 +1,6 @@ +--- +'@backstage/backend-tasks': patch +'@backstage/plugin-catalog-backend': patch +--- + +Added support to mysql on some raw queries diff --git a/.changeset/five-falcons-destroy.md b/.changeset/five-falcons-destroy.md deleted file mode 100644 index 481c2a38ea..0000000000 --- a/.changeset/five-falcons-destroy.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Add `copyWithoutTemplating` to the fetch template action input. `copyWithoutTemplating` also accepts an array of glob patterns. Contents of matched files or directories are copied without being processed, but paths are subject to rendering. - -Deprecate `copyWithoutRender` in favor of `copyWithoutTemplating`. diff --git a/.changeset/five-fireants-run.md b/.changeset/five-fireants-run.md deleted file mode 100644 index 589d46cc81..0000000000 --- a/.changeset/five-fireants-run.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Fix the EntityLayout header style so that EntityContextMenu button can display in correct shape when user hover on it diff --git a/.changeset/forty-seals-complain.md b/.changeset/forty-seals-complain.md deleted file mode 100644 index b2435b2d3a..0000000000 --- a/.changeset/forty-seals-complain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Improve error messaging when passing in malformed auth diff --git a/.changeset/fresh-rabbits-juggle.md b/.changeset/fresh-rabbits-juggle.md new file mode 100644 index 0000000000..804ae70853 --- /dev/null +++ b/.changeset/fresh-rabbits-juggle.md @@ -0,0 +1,9 @@ +--- +'@backstage/plugin-dynatrace': minor +--- + +New features: + +- Some visual improvements to the table that displays Problems +- Added support for viewing recent Synthetics results using +- Added some additional linking to the configured Dynatrace instance diff --git a/.changeset/funny-fireants-shop.md b/.changeset/funny-fireants-shop.md deleted file mode 100644 index 8e6d997aa2..0000000000 --- a/.changeset/funny-fireants-shop.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-newrelic-dashboard': minor ---- - -Fix bug where the default time window/snapshot duration was supposed to be 30 days, but ended up being 43 weeks - -**BREAKING**: Add a select input to change the time window of the snapshot displayed. This removes the duration prop from the `DashboardSnapshot` component. diff --git a/.changeset/gorgeous-swans-kiss.md b/.changeset/gorgeous-swans-kiss.md new file mode 100644 index 0000000000..c33eb49d73 --- /dev/null +++ b/.changeset/gorgeous-swans-kiss.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-github': patch +--- + +New experimental alpha exports for use with the upcoming backend system. diff --git a/.changeset/great-roses-pump.md b/.changeset/great-roses-pump.md deleted file mode 100644 index 0e15d186d4..0000000000 --- a/.changeset/great-roses-pump.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Previously, the color of the Entity Context Menu (in the Entity Page Header) was hardcoded as `white`. - -This was an issue for themes that use a header with a white background. By default, the color of the icon is now `theme.page.fontColor`. - -It can now also be overridden in the theme, which is only necessary if the header title, subtitle and three-dots icon need to have different colors. For example: - -```typescript -export function createThemeOverrides(theme: BackstageTheme): Overrides { - return { - PluginCatalogEntityContextMenu: { - button: { - color: 'blue', - }, - }, - ... - }, - ... - } -``` diff --git a/.changeset/green-actors-argue.md b/.changeset/green-actors-argue.md deleted file mode 100644 index e21fbb040c..0000000000 --- a/.changeset/green-actors-argue.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -'@backstage/cli': minor ---- - -**BREAKING**: Removed the following deprecated package commands: - -- `app:build` - Use `package build` instead -- `app:serve` - Use `package start` instead -- `backend:build` - Use `package build` instead -- `backend:bundle` - Use `package build` instead -- `backend:dev` - Use `package start` instead -- `plugin:build` - Use `package build` instead -- `plugin:serve` - Use `package start` instead -- `build` - Use `package build` instead -- `lint` - Use `package lint` instead -- `prepack` - Use `package prepack` instead -- `postpack` - Use `package postpack` instead - -In order to replace these you need to have [migrated to using package roles](https://backstage.io/docs/tutorials/package-role-migration). diff --git a/.changeset/happy-boxes-melt.md b/.changeset/happy-boxes-melt.md deleted file mode 100644 index c478e783d3..0000000000 --- a/.changeset/happy-boxes-melt.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@techdocs/cli': patch -'@backstage/plugin-techdocs-node': patch ---- - -Fix the flag parsing for `legacyCopyReadmeMdToIndexMd` in `techdocs-cli generate` command, and decouple it's logic from the `techdocs-ref` flag. diff --git a/.changeset/create-app-1657631847.md b/.changeset/happy-kiwis-look.md similarity index 57% rename from .changeset/create-app-1657631847.md rename to .changeset/happy-kiwis-look.md index b50d431d4b..ff0da8943b 100644 --- a/.changeset/create-app-1657631847.md +++ b/.changeset/happy-kiwis-look.md @@ -2,4 +2,4 @@ '@backstage/create-app': patch --- -Bumped create-app version. +Fix typo in the documentation diff --git a/.changeset/hip-ways-shop.md b/.changeset/hip-ways-shop.md deleted file mode 100644 index 74646b7b3a..0000000000 --- a/.changeset/hip-ways-shop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes': patch ---- - -expose detectErrors function publicly diff --git a/.changeset/hot-files-begin.md b/.changeset/hot-files-begin.md new file mode 100644 index 0000000000..e9b9076986 --- /dev/null +++ b/.changeset/hot-files-begin.md @@ -0,0 +1,71 @@ +--- +'@backstage/create-app': patch +--- + +The `packages/backend/Dockerfile` received a couple of updates, it now looks as follows: + +```Dockerfile +FROM node:16-bullseye-slim + +# Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, +# in which case you should also move better-sqlite3 to "devDependencies" in package.json. +RUN apt-get update && \ + apt-get install -y --no-install-recommends libsqlite3-dev python3 build-essential && \ + rm -rf /var/lib/apt/lists/* && \ + yarn config set python /usr/bin/python3 + +# From here on we use the least-privileged `node` user to run the backend. +USER node +WORKDIR /app + +# This switches many Node.js dependencies to production mode. +ENV NODE_ENV production + +# Copy repo skeleton first, to avoid unnecessary docker cache invalidation. +# The skeleton contains the package.json of each package in the monorepo, +# and along with yarn.lock and the root package.json, that's enough to run yarn install. +COPY --chown=node:node yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./ +RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz + +RUN yarn install --frozen-lockfile --production --network-timeout 300000 && rm -rf "$(yarn cache dir)" + +# Then copy the rest of the backend bundle, along with any other files we might want. +COPY --chown=node:node packages/backend/dist/bundle.tar.gz app-config*.yaml ./ +RUN tar xzf bundle.tar.gz && rm bundle.tar.gz + +CMD ["node", "packages/backend", "--config", "app-config.yaml", "--config", "app-config.production.yaml"] +``` + +The two notable changes are that a `USER node` instruction has been added and the ordering of instructions has been changed accordingly. This means that the app will now be running using the least-privileged `node` user. In order for this to work we now need to make sure that all app files are owned by the `node` user, which we do by adding the `--chown=node:node` option to the `COPY` instructions. + +The second change is the addition of `ENV NODE_ENV production`, which ensured that all Node.js modules run in production mode. If you apply this change to an existing app, note that one of the more significant changes is that this switches the log formatting to use the default production format, JSON. Rather than your log lines looking like this: + +```log +2022-08-10T11:36:05.478Z catalog info Performing database migration type=plugin +``` + +They will now look like this: + +```log +{"level":"info","message":"Performing database migration","plugin":"catalog","service":"backstage","type":"plugin"} +``` + +If you wish to keep the existing format, you can override this change by applying the following change to `packages/backend/src/index.ts`: + +```diff + getRootLogger, ++ setRootLogger, ++ createRootLogger, ++ coloredFormat, + useHotMemoize, + ... + ServerTokenManager, + } from '@backstage/backend-common'; + + ... + + async function main() { ++ setRootLogger(createRootLogger({ format: coloredFormat })); ++ + const config = await loadBackendConfig({ +``` diff --git a/.changeset/hot-rice-sin.md b/.changeset/hot-rice-sin.md deleted file mode 100644 index 5a3d6fdb7a..0000000000 --- a/.changeset/hot-rice-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -Add `allowedRepos` `ui:option` to `RepoUrlPicker` component, and move `repoName` field to own component diff --git a/.changeset/hot-suits-glow.md b/.changeset/hot-suits-glow.md new file mode 100644 index 0000000000..e394d3b8c0 --- /dev/null +++ b/.changeset/hot-suits-glow.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-cost-insights': patch +--- + +The `CostInsightsHeader`component now uses group names if available diff --git a/.changeset/hungry-cougars-press.md b/.changeset/hungry-cougars-press.md deleted file mode 100644 index c99e1f4c76..0000000000 --- a/.changeset/hungry-cougars-press.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-ldap': patch ---- - -Fix mapping between users and groups for FreeIPA when using the LdapOrgProcessor diff --git a/.changeset/hungry-dogs-agree.md b/.changeset/hungry-dogs-agree.md new file mode 100644 index 0000000000..b111b6e463 --- /dev/null +++ b/.changeset/hungry-dogs-agree.md @@ -0,0 +1,6 @@ +--- +'@backstage/core-app-api': patch +'@backstage/core-plugin-api': patch +--- + +Added `getSystemIcons()` function to the `AppContext` available through `useApp` that will pull a list of all the icons that have been registered in the App. diff --git a/.changeset/itchy-stingrays-greet.md b/.changeset/itchy-stingrays-greet.md deleted file mode 100644 index ed409abbe3..0000000000 --- a/.changeset/itchy-stingrays-greet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-aws': patch ---- - -Add processor for ingesting EKS clusters into the catalog diff --git a/.changeset/large-kangaroos-poke.md b/.changeset/large-kangaroos-poke.md deleted file mode 100644 index 3a9444cfa1..0000000000 --- a/.changeset/large-kangaroos-poke.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@backstage/create-app': patch ---- - -Added an explicit `node-gyp` dependency to the root `package.json`. This is to work around a bug in older versions of `node-gyp` that causes Python execution to fail on macOS. - -You can add this workaround to your existing project by adding `node-gyp` as a `devDependency` in your root `package.json` file: - -```diff - "devDependencies": { -+ "node-gyp": "^9.0.0" - }, -``` diff --git a/.changeset/lazy-snakes-film.md b/.changeset/lazy-snakes-film.md new file mode 100644 index 0000000000..ffb9c539c8 --- /dev/null +++ b/.changeset/lazy-snakes-film.md @@ -0,0 +1,5 @@ +--- +'@backstage/core-components': patch +--- + +Adds code to generate ids for headers parsed through the MarkdownContent component. diff --git a/.changeset/lazy-steaks-tell.md b/.changeset/lazy-steaks-tell.md deleted file mode 100644 index 5e63816ada..0000000000 --- a/.changeset/lazy-steaks-tell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-node': minor ---- - -Added alpha exports for the new experimental backend system. diff --git a/.changeset/lemon-goats-obey.md b/.changeset/lemon-goats-obey.md deleted file mode 100644 index 7bdb59bd61..0000000000 --- a/.changeset/lemon-goats-obey.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-apache-airflow': minor ---- - -Exposed DagTableComponent as standalone component + added a prop to get only select DAGs instead of the full list diff --git a/.changeset/light-beans-share.md b/.changeset/light-beans-share.md new file mode 100644 index 0000000000..51c59ff7d0 --- /dev/null +++ b/.changeset/light-beans-share.md @@ -0,0 +1,16 @@ +--- +'@backstage/plugin-search-backend-module-pg': minor +--- + +Fixed a bug in search-backend-module-pg where it ignores the skip migration database options when using the database. + +To use this new implementation you need to create the instance of `DatabaseDocumentStore` using the `PluginDatabaseManager` instead of `Knex`; + +``` +import { DatabaseManager, getRootLogger, loadBackendConfig } from '@backstage/backend-common'; +import { DatabaseDocumentStore } from '@backstage/plugin-search-backend-module-pg'; + +const config = await loadBackendConfig({ argv: process.argv, logger: getRootLogger() }); +const databaseManager = DatabaseManager.fromConfig(config, { migrations: { skip: true } }); +const databaseDocumentStore = await DatabaseDocumentStore.create(databaseManager); +``` diff --git a/.changeset/light-hornets-eat.md b/.changeset/light-hornets-eat.md deleted file mode 100644 index 795e51fb67..0000000000 --- a/.changeset/light-hornets-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-cost-insights-common': minor ---- - -Introduces a new isomorphic @backstage/plugin-cost-insight-common package to contain shared types across all other cost insights packages and modules. diff --git a/.changeset/little-geckos-end.md b/.changeset/little-geckos-end.md deleted file mode 100644 index 328095aa44..0000000000 --- a/.changeset/little-geckos-end.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': minor ---- - -Add new endpoints to Kubernetes backend plugin - -BREAKING: Kubernetes backend plugin now depends on CatalogApi - -```typescript -// Create new CatalogClient -const catalogApi = new CatalogClient({ discoveryApi: env.discovery }); -const { router } = await KubernetesBuilder.createBuilder({ - logger: env.logger, - config: env.config, - // Inject it into createBuilder params - catalogApi, -}).build(); -``` diff --git a/.changeset/little-guests-sell.md b/.changeset/little-guests-sell.md deleted file mode 100644 index 91f578ee38..0000000000 --- a/.changeset/little-guests-sell.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/app-defaults': patch -'@backstage/core-app-api': patch -'@backstage/core-plugin-api': patch ---- - -Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. diff --git a/.changeset/long-bananas-rescue.md b/.changeset/long-bananas-rescue.md deleted file mode 100644 index d990fd67c6..0000000000 --- a/.changeset/long-bananas-rescue.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-msgraph': minor ---- - -Align `msgraph` plugin's entity provider config with other providers. **Deprecated** entity processor as well as previous config. - -You will see warning at the log output until you migrate to the new setup. -All deprecated parts will be removed eventually after giving some time to migrate. - -Please find information on how to migrate your current setup to the new one below. - -**Migration Guide:** - -There were two different way on how to use the msgraph plugin: processor or provider. - -Previous registration for the processor: - -```typescript -// packages/backend/src/plugins/catalog.ts -builder.addProcessor( - MicrosoftGraphOrgReaderProcessor.fromConfig(env.config, { - logger: env.logger, - // [...] - }), -); -``` - -Previous registration when using the provider: - -```typescript -// packages/backend/src/plugins/catalog.ts -builder.addEntityProvider( - MicrosoftGraphOrgEntityProvider.fromConfig(env.config, { - id: 'https://graph.microsoft.com/v1.0', - target: 'https://graph.microsoft.com/v1.0', - logger: env.logger, - schedule: env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 30 }, - timeout: { minutes: 3 }, - }), - // [...] - }), -); -``` - -Previous configuration as used for both: - -```yaml -# app-config.yaml -catalog: - processors: - microsoftGraphOrg: - providers: - - target: https://graph.microsoft.com/v1.0 - # [...] -``` - -**Replacement:** - -Please check https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-msgraph/README.md for the complete documentation of all configuration options (config as well as registration of the provider). - -```yaml -# app-config.yaml -catalog: - providers: - microsoftGraphOrg: - # In case you used the deprecated configuration with the entity provider - # using the value of `target` will keep the same location key for all - providerId: # some stable ID which will be used as part of the location key for all ingested data - target: https://graph.microsoft.com/v1.0 - # [...] -``` - -```typescript -// packages/backend/src/plugins/catalog.ts -builder.addEntityProvider( - MicrosoftGraphOrgEntityProvider.fromConfig(env.config, { - logger: env.logger, - schedule: env.scheduler.createScheduledTaskRunner({ - frequency: { minutes: 30 }, - timeout: { minutes: 3 }, - }), - // [...] - }), -); -``` - -In case you've used multiple entity providers before -**and** you had different transformers for each of them -you can provide these directly at the one `fromConfig` call -by passing a Record with the provider ID as key. diff --git a/.changeset/loud-lemons-listen.md b/.changeset/loud-lemons-listen.md deleted file mode 100644 index f232c1491e..0000000000 --- a/.changeset/loud-lemons-listen.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-node': major ---- - -This package houses stable types from the `@backstage/plugin-catalog-backend` package and is intended for creation of catalog modules. Prefer importing from this package over the `@backstage/plugin-catalog-backend` package. diff --git a/.changeset/lucky-points-wash.md b/.changeset/lucky-points-wash.md new file mode 100644 index 0000000000..961c354574 --- /dev/null +++ b/.changeset/lucky-points-wash.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-org': patch +--- + +Added an edit button to the `UserProfileCard` that is enabled when the `backstage.io/edit-url` is present, this matches how the `GroupProfileCard` works diff --git a/.changeset/many-vans-thank.md b/.changeset/many-vans-thank.md deleted file mode 100644 index 16f8c8a69b..0000000000 --- a/.changeset/many-vans-thank.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-jenkins': patch -'@backstage/plugin-jenkins-backend': patch ---- - -feature: added support for multiple branches to the `JenkinsApi` diff --git a/.changeset/mean-adults-argue.md b/.changeset/mean-adults-argue.md deleted file mode 100644 index 22eacab054..0000000000 --- a/.changeset/mean-adults-argue.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-proxy-backend': patch ---- - -The proxy-backend now automatically reloads configuration when app-config.yaml is updated. diff --git a/.changeset/mean-berries-kick.md b/.changeset/mean-berries-kick.md deleted file mode 100644 index 7726c2c79e..0000000000 --- a/.changeset/mean-berries-kick.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Moving from Bitbucket Server endpoint from https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp222 to https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp224, to have the last commit in function of different branch, and not only the list of default branch diff --git a/.changeset/metal-singers-matter.md b/.changeset/metal-singers-matter.md deleted file mode 100644 index 2c8d370790..0000000000 --- a/.changeset/metal-singers-matter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Upgrade `@rollup/plugin-node-resolve` to `^13.0.6` diff --git a/.changeset/metal-windows-share.md b/.changeset/metal-windows-share.md deleted file mode 100644 index b4443a620f..0000000000 --- a/.changeset/metal-windows-share.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-pg': patch ---- - -**DEPRECATED**: `PgSearchEngine` static `from` has been deprecated and will be removed in a future release. Use static `fromConfig` method to instantiate. - -Added support for highlighting matched terms in search result data diff --git a/.changeset/modern-ducks-lay.md b/.changeset/modern-ducks-lay.md deleted file mode 100644 index bd62c309ba..0000000000 --- a/.changeset/modern-ducks-lay.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-stack-overflow': patch ---- - -- Publicly exports `StackOverflowIcon`. -- `HomePageStackOverflowQuestions` accepts optional icon property. diff --git a/.changeset/moody-crabs-march.md b/.changeset/moody-crabs-march.md deleted file mode 100644 index b5ddf12ffa..0000000000 --- a/.changeset/moody-crabs-march.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-vault': patch -'@backstage/plugin-vault-backend': patch ---- - -Added a path notion in addition to secret name to allow to differentiate secrets in sub-paths diff --git a/.changeset/nasty-zoos-cross.md b/.changeset/nasty-zoos-cross.md deleted file mode 100644 index 7a658d7209..0000000000 --- a/.changeset/nasty-zoos-cross.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-github-pull-requests-board': patch ---- - -Support namespaced teams and fetch all kinds diff --git a/.changeset/nervous-hounds-matter.md b/.changeset/nervous-hounds-matter.md deleted file mode 100644 index 0f60b7ae2c..0000000000 --- a/.changeset/nervous-hounds-matter.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -contextMenu prop passed through to from the component diff --git a/.changeset/nervous-humans-sip.md b/.changeset/nervous-humans-sip.md deleted file mode 100644 index aa1ca2c60a..0000000000 --- a/.changeset/nervous-humans-sip.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-app-api': patch ---- - -The `signOut` method of the `IdentityApi` will now navigate the user back to the base URL of the app as indicated by the `app.baseUrl` config. diff --git a/.changeset/nice-seas-jam.md b/.changeset/nice-seas-jam.md deleted file mode 100644 index 6e642b33b3..0000000000 --- a/.changeset/nice-seas-jam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-node': patch ---- - -Fixed issue with git feedback buttons not appearing automatically in docs pages. This was done by appending `repo_url` to the helper function `getRepoUrlFromLocationAnnotation`. diff --git a/.changeset/ninety-coats-learn.md b/.changeset/ninety-coats-learn.md deleted file mode 100644 index 9d6945e9c0..0000000000 --- a/.changeset/ninety-coats-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Fix relative `sub-paths` by concatenating the app's base path with them. diff --git a/.changeset/old-onions-hear.md b/.changeset/old-onions-hear.md deleted file mode 100644 index 82dcc09190..0000000000 --- a/.changeset/old-onions-hear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor ---- - -Update GitLab Merge Request Action to allow source branch to be deleted diff --git a/.changeset/old-tables-joke.md b/.changeset/old-tables-joke.md new file mode 100644 index 0000000000..d458244b3a --- /dev/null +++ b/.changeset/old-tables-joke.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +Simplified the `ServiceFactory` type and removed `AnyServiceFactory`. diff --git a/.changeset/orange-deers-marry.md b/.changeset/orange-deers-marry.md deleted file mode 100644 index c565111b60..0000000000 --- a/.changeset/orange-deers-marry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Fix issues with optional directories and files diff --git a/.changeset/perfect-donuts-applaud.md b/.changeset/perfect-donuts-applaud.md deleted file mode 100644 index 3b663fa2c2..0000000000 --- a/.changeset/perfect-donuts-applaud.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Don't resolve symlinks, treat them as binary files and copy them as-is diff --git a/.changeset/pink-cars-pretend.md b/.changeset/pink-cars-pretend.md deleted file mode 100644 index c46cb99f55..0000000000 --- a/.changeset/pink-cars-pretend.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -new setUserAsOwner flag for publish:gitlab action - -The field default is `false`. When true it will use the token configured in the gitlab integration for the matching host, to try and set the user logged in via `repoUrlPicker` `requestUserCredentials` OAuth flow as owner of the repository created in GitLab. diff --git a/.changeset/plenty-books-peel.md b/.changeset/plenty-books-peel.md deleted file mode 100644 index 423c6f8bd4..0000000000 --- a/.changeset/plenty-books-peel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch ---- - -Add support for Kubernetes clusters in the catalog. diff --git a/.changeset/plenty-clouds-guess.md b/.changeset/plenty-clouds-guess.md deleted file mode 100644 index cc56bd604d..0000000000 --- a/.changeset/plenty-clouds-guess.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Added an option for the auth backend router to select the algorithm for the JWT token signing keys diff --git a/.changeset/polite-keys-confess.md b/.changeset/polite-keys-confess.md deleted file mode 100644 index 007ad98641..0000000000 --- a/.changeset/polite-keys-confess.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-msgraph': minor ---- - -Microsoft Graph plugin can supports many more options for authenticating with the Microsoft Graph API. -Previously only ClientId/ClientSecret was supported, but now all the authentication options of `DefaultAzureCredential` from `@azure/identity` are supported. -Including Managed Identity, Client Certificate, Azure CLI and VS Code. - -If `clientId` and `clientSecret` are specified in configuration, the plugin behaves the same way as before. -If these fields are omitted, the plugin uses `DefaultAzureCredential` to automatically determine the best authentication method. -This is particularly useful for local development environments - the default configuration will try to use existing credentials from Visual Studio Code, Azure CLI and Azure PowerShell, without the user needing to configure any credentials in app-config.yaml diff --git a/.changeset/polite-lions-sell.md b/.changeset/polite-lions-sell.md deleted file mode 100644 index 07b5fcbd77..0000000000 --- a/.changeset/polite-lions-sell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Auth provider now also export createAuthProviderIntegration diff --git a/.changeset/polite-moose-beam.md b/.changeset/polite-moose-beam.md deleted file mode 100644 index 5e41018ae6..0000000000 --- a/.changeset/polite-moose-beam.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': minor ---- - -Export experimental `catalogPlugin` for the new backend system. This export is not considered stable and should not be used in production. diff --git a/.changeset/popular-pots-yell.md b/.changeset/popular-pots-yell.md deleted file mode 100644 index f0decc9fb8..0000000000 --- a/.changeset/popular-pots-yell.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@backstage/plugin-auth-backend': minor ---- - -**BREAKING**: Removed all directly exported auth provider factories, option types, and sign-in resolvers. For example: `AwsAlbProviderOptions`, `bitbucketUserIdSignInResolver`, `createGithubProvider`. These are all still accessible via the `providers` export. For example, use `providers.github.create()` rather than `createGithubProvider()`, and `providers.bitbucket.resolvers.userIdMatchingUserEntityAnnotation()` rather than `bitbucketUserIdSignInResolver`. - -**BREAKING**: Removed the exported `AuthProviderFactoryOptions` type as well as the deprecated option fields of the `AuthProviderFactory` callback. This includes the `tokenManager`, `tokenIssuer`, `discovery`, and `catalogApi` fields. Existing usage of these should be replaced with the new utilities in the `resolverContext` field. The deprecated `TokenIssuer` type is now also removed, since it is no longer used. - -**BREAKING**: Removed `getEntityClaims`, use `getDefaultOwnershipEntityRefs` instead. - -**DEPRECATION**: Deprecated `AtlassianAuthProvider` as it was unintentionally exported. diff --git a/.changeset/popular-starfishes-reflect.md b/.changeset/popular-starfishes-reflect.md deleted file mode 100644 index e02eaf7102..0000000000 --- a/.changeset/popular-starfishes-reflect.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/integration': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-git-release-manager': patch -'@backstage/plugin-github-actions': patch -'@backstage/plugin-github-pull-requests-board': patch ---- - -Upgrade @octokit/rest to 19.0.3 diff --git a/.changeset/pre.json b/.changeset/pre.json index 62ec58c896..172b96d8f6 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,313 +1,175 @@ { - "mode": "exit", + "mode": "pre", "tag": "next", "initialVersions": { - "example-app": "0.2.72", - "@backstage/app-defaults": "1.0.3", - "example-backend": "0.2.72", - "@backstage/backend-common": "0.14.0", - "@backstage/backend-tasks": "0.3.2", - "@backstage/backend-test-utils": "0.1.25", - "@backstage/catalog-client": "1.0.3", - "@backstage/catalog-model": "1.0.3", - "@backstage/cli": "0.17.2", + "example-app": "0.2.74", + "@backstage/app-defaults": "1.0.5", + "example-backend": "0.2.74", + "@backstage/backend-app-api": "0.2.0", + "@backstage/backend-common": "0.15.0", + "@backstage/backend-defaults": "0.1.0", + "example-backend-next": "0.0.2", + "@backstage/backend-plugin-api": "0.1.1", + "@backstage/backend-tasks": "0.3.4", + "@backstage/backend-test-utils": "0.1.27", + "@backstage/catalog-client": "1.0.4", + "@backstage/catalog-model": "1.1.0", + "@backstage/cli": "0.18.1", "@backstage/cli-common": "0.1.9", "@backstage/codemods": "0.1.38", "@backstage/config": "1.0.1", - "@backstage/config-loader": "1.1.2", - "@backstage/core-app-api": "1.0.3", - "@backstage/core-components": "0.9.5", - "@backstage/core-plugin-api": "1.0.3", - "@backstage/create-app": "0.4.28", - "@backstage/dev-utils": "1.0.3", + "@backstage/config-loader": "1.1.3", + "@backstage/core-app-api": "1.0.5", + "@backstage/core-components": "0.11.0", + "@backstage/core-plugin-api": "1.0.5", + "@backstage/create-app": "0.4.30", + "@backstage/dev-utils": "1.0.5", "e2e-test": "0.2.0", - "@backstage/errors": "1.0.0", - "@backstage/integration": "1.2.1", - "@backstage/integration-react": "1.1.1", - "@backstage/release-manifests": "0.0.4", - "@techdocs/cli": "1.1.2", - "techdocs-cli-embedded-app": "0.2.71", - "@backstage/test-utils": "1.1.1", - "@backstage/theme": "0.2.15", + "@backstage/errors": "1.1.0", + "@backstage/integration": "1.3.0", + "@backstage/integration-react": "1.1.3", + "@backstage/release-manifests": "0.0.5", + "@techdocs/cli": "1.2.0", + "techdocs-cli-embedded-app": "0.2.73", + "@backstage/test-utils": "1.1.3", + "@backstage/theme": "0.2.16", "@backstage/types": "1.0.0", "@backstage/version-bridge": "1.0.1", - "@backstage/plugin-adr": "0.1.1", - "@backstage/plugin-adr-backend": "0.1.1", - "@backstage/plugin-adr-common": "0.1.1", - "@backstage/plugin-airbrake": "0.3.6", - "@backstage/plugin-airbrake-backend": "0.2.6", - "@backstage/plugin-allure": "0.1.22", - "@backstage/plugin-analytics-module-ga": "0.1.17", - "@backstage/plugin-apache-airflow": "0.1.14", - "@backstage/plugin-api-docs": "0.8.6", - "@backstage/plugin-app-backend": "0.3.33", - "@backstage/plugin-auth-backend": "0.14.1", - "@backstage/plugin-auth-node": "0.2.2", - "@backstage/plugin-azure-devops": "0.1.22", - "@backstage/plugin-azure-devops-backend": "0.3.12", - "@backstage/plugin-azure-devops-common": "0.2.3", - "@backstage/plugin-badges": "0.2.30", - "@backstage/plugin-badges-backend": "0.1.27", - "@backstage/plugin-bazaar": "0.1.21", - "@backstage/plugin-bazaar-backend": "0.1.17", - "@backstage/plugin-bitbucket-cloud-common": "0.1.0", - "@backstage/plugin-bitrise": "0.1.33", - "@backstage/plugin-catalog": "1.3.0", - "@backstage/plugin-catalog-backend": "1.2.0", - "@backstage/plugin-catalog-backend-module-aws": "0.1.6", - "@backstage/plugin-catalog-backend-module-azure": "0.1.4", - "@backstage/plugin-catalog-backend-module-bitbucket": "0.2.0", - "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.1.0", - "@backstage/plugin-catalog-backend-module-gerrit": "0.1.1", - "@backstage/plugin-catalog-backend-module-github": "0.1.4", - "@backstage/plugin-catalog-backend-module-gitlab": "0.1.4", - "@backstage/plugin-catalog-backend-module-ldap": "0.5.0", - "@backstage/plugin-catalog-backend-module-msgraph": "0.3.3", - "@backstage/plugin-catalog-common": "1.0.3", - "@backstage/plugin-catalog-graph": "0.2.18", - "@backstage/plugin-catalog-graphql": "0.3.10", - "@backstage/plugin-catalog-import": "0.8.9", - "@backstage/plugin-catalog-react": "1.1.1", - "@backstage/plugin-cicd-statistics": "0.1.8", - "@backstage/plugin-cicd-statistics-module-gitlab": "0.1.2", - "@backstage/plugin-circleci": "0.3.6", - "@backstage/plugin-cloudbuild": "0.3.6", - "@backstage/plugin-code-climate": "0.1.6", - "@backstage/plugin-code-coverage": "0.1.33", - "@backstage/plugin-code-coverage-backend": "0.1.31", - "@backstage/plugin-codescene": "0.1.1", - "@backstage/plugin-config-schema": "0.1.29", - "@backstage/plugin-cost-insights": "0.11.28", - "@backstage/plugin-dynatrace": "0.1.0", - "@internal/plugin-todo-list": "1.0.2", - "@internal/plugin-todo-list-backend": "1.0.2", - "@internal/plugin-todo-list-common": "1.0.2", - "@backstage/plugin-explore": "0.3.37", - "@backstage/plugin-explore-react": "0.0.18", - "@backstage/plugin-firehydrant": "0.1.23", - "@backstage/plugin-fossa": "0.2.38", - "@backstage/plugin-gcalendar": "0.3.2", - "@backstage/plugin-gcp-projects": "0.3.25", - "@backstage/plugin-git-release-manager": "0.3.19", - "@backstage/plugin-github-actions": "0.5.6", - "@backstage/plugin-github-deployments": "0.1.37", - "@backstage/plugin-github-pull-requests-board": "0.1.0", - "@backstage/plugin-gitops-profiles": "0.3.24", - "@backstage/plugin-gocd": "0.1.12", - "@backstage/plugin-graphiql": "0.2.38", - "@backstage/plugin-graphql-backend": "0.1.23", - "@backstage/plugin-home": "0.4.22", - "@backstage/plugin-ilert": "0.1.32", - "@backstage/plugin-jenkins": "0.7.5", - "@backstage/plugin-jenkins-backend": "0.1.23", - "@backstage/plugin-jenkins-common": "0.1.5", - "@backstage/plugin-kafka": "0.3.6", - "@backstage/plugin-kafka-backend": "0.2.26", - "@backstage/plugin-kubernetes": "0.6.6", - "@backstage/plugin-kubernetes-backend": "0.6.0", - "@backstage/plugin-kubernetes-common": "0.3.0", - "@backstage/plugin-lighthouse": "0.3.6", - "@backstage/plugin-newrelic": "0.3.24", - "@backstage/plugin-newrelic-dashboard": "0.1.14", - "@backstage/plugin-org": "0.5.6", - "@backstage/plugin-pagerduty": "0.4.0", - "@backstage/plugin-periskop": "0.1.4", - "@backstage/plugin-periskop-backend": "0.1.4", - "@backstage/plugin-permission-backend": "0.5.8", - "@backstage/plugin-permission-common": "0.6.2", - "@backstage/plugin-permission-node": "0.6.2", - "@backstage/plugin-permission-react": "0.4.2", - "@backstage/plugin-proxy-backend": "0.2.27", - "@backstage/plugin-rollbar": "0.4.6", - "@backstage/plugin-rollbar-backend": "0.1.30", - "@backstage/plugin-scaffolder": "1.3.0", - "@backstage/plugin-scaffolder-backend": "1.3.0", - "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.8", - "@backstage/plugin-scaffolder-backend-module-rails": "0.4.1", - "@backstage/plugin-scaffolder-backend-module-yeoman": "0.2.6", - "@backstage/plugin-scaffolder-common": "1.1.1", - "@backstage/plugin-search": "0.9.0", - "@backstage/plugin-search-backend": "0.5.3", - "@backstage/plugin-search-backend-module-elasticsearch": "0.1.5", - "@backstage/plugin-search-backend-module-pg": "0.3.4", - "@backstage/plugin-search-backend-node": "0.6.2", - "@backstage/plugin-search-common": "0.3.5", - "@backstage/plugin-search-react": "0.2.1", - "@backstage/plugin-sentry": "0.3.44", - "@backstage/plugin-shortcuts": "0.2.7", - "@backstage/plugin-sonarqube": "0.3.6", - "@backstage/plugin-splunk-on-call": "0.3.30", - "@backstage/plugin-stack-overflow": "0.1.2", - "@backstage/plugin-stack-overflow-backend": "0.1.2", - "@backstage/plugin-tech-insights": "0.2.2", - "@backstage/plugin-tech-insights-backend": "0.4.1", - "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.17", - "@backstage/plugin-tech-insights-common": "0.2.4", - "@backstage/plugin-tech-insights-node": "0.3.1", - "@backstage/plugin-tech-radar": "0.5.13", - "@backstage/plugin-techdocs": "1.2.0", - "@backstage/plugin-techdocs-addons-test-utils": "1.0.1", - "@backstage/plugin-techdocs-backend": "1.1.2", - "@backstage/plugin-techdocs-module-addons-contrib": "1.0.1", - "@backstage/plugin-techdocs-node": "1.1.2", - "@backstage/plugin-techdocs-react": "1.0.1", - "@backstage/plugin-todo": "0.2.8", - "@backstage/plugin-todo-backend": "0.1.30", - "@backstage/plugin-user-settings": "0.4.5", - "@backstage/plugin-vault": "0.1.0", - "@backstage/plugin-vault-backend": "0.1.0", - "@backstage/plugin-xcmetrics": "0.2.26", - "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.0.0", - "@backstage/plugin-catalog-backend-module-openapi": "0.0.0", - "@backstage/plugin-cost-insights-common": "0.0.0", - "@backstage/backend-app-api": "0.0.0", - "example-backend-next": "0.0.0", - "@backstage/backend-plugin-api": "0.0.0", - "@backstage/plugin-catalog-node": "0.0.0" + "@backstage/plugin-adr": "0.2.0", + "@backstage/plugin-adr-backend": "0.2.0", + "@backstage/plugin-adr-common": "0.2.0", + "@backstage/plugin-airbrake": "0.3.8", + "@backstage/plugin-airbrake-backend": "0.2.8", + "@backstage/plugin-allure": "0.1.24", + "@backstage/plugin-analytics-module-ga": "0.1.19", + "@backstage/plugin-apache-airflow": "0.2.1", + "@backstage/plugin-api-docs": "0.8.8", + "@backstage/plugin-api-docs-module-protoc-gen-doc": "0.1.0", + "@backstage/plugin-apollo-explorer": "0.1.1", + "@backstage/plugin-app-backend": "0.3.35", + "@backstage/plugin-auth-backend": "0.15.1", + "@backstage/plugin-auth-node": "0.2.4", + "@backstage/plugin-azure-devops": "0.1.24", + "@backstage/plugin-azure-devops-backend": "0.3.14", + "@backstage/plugin-azure-devops-common": "0.2.4", + "@backstage/plugin-badges": "0.2.32", + "@backstage/plugin-badges-backend": "0.1.29", + "@backstage/plugin-bazaar": "0.1.23", + "@backstage/plugin-bazaar-backend": "0.1.19", + "@backstage/plugin-bitbucket-cloud-common": "0.1.2", + "@backstage/plugin-bitrise": "0.1.35", + "@backstage/plugin-catalog": "1.5.0", + "@backstage/plugin-catalog-backend": "1.3.1", + "@backstage/plugin-catalog-backend-module-aws": "0.1.8", + "@backstage/plugin-catalog-backend-module-azure": "0.1.6", + "@backstage/plugin-catalog-backend-module-bitbucket": "0.2.2", + "@backstage/plugin-catalog-backend-module-bitbucket-cloud": "0.1.2", + "@backstage/plugin-catalog-backend-module-bitbucket-server": "0.1.0", + "@backstage/plugin-catalog-backend-module-gerrit": "0.1.3", + "@backstage/plugin-catalog-backend-module-github": "0.1.6", + "@backstage/plugin-catalog-backend-module-gitlab": "0.1.6", + "@backstage/plugin-catalog-backend-module-ldap": "0.5.2", + "@backstage/plugin-catalog-backend-module-msgraph": "0.4.1", + "@backstage/plugin-catalog-backend-module-openapi": "0.1.1", + "@backstage/plugin-catalog-common": "1.0.5", + "@internal/plugin-catalog-customized": "0.0.1", + "@backstage/plugin-catalog-graph": "0.2.20", + "@backstage/plugin-catalog-graphql": "0.3.12", + "@backstage/plugin-catalog-import": "0.8.11", + "@backstage/plugin-catalog-node": "1.0.1", + "@backstage/plugin-catalog-react": "1.1.3", + "@backstage/plugin-cicd-statistics": "0.1.10", + "@backstage/plugin-cicd-statistics-module-gitlab": "0.1.4", + "@backstage/plugin-circleci": "0.3.8", + "@backstage/plugin-cloudbuild": "0.3.8", + "@backstage/plugin-code-climate": "0.1.8", + "@backstage/plugin-code-coverage": "0.2.1", + "@backstage/plugin-code-coverage-backend": "0.2.1", + "@backstage/plugin-codescene": "0.1.3", + "@backstage/plugin-config-schema": "0.1.31", + "@backstage/plugin-cost-insights": "0.11.30", + "@backstage/plugin-cost-insights-common": "0.1.1", + "@backstage/plugin-dynatrace": "0.1.2", + "@internal/plugin-todo-list": "1.0.4", + "@internal/plugin-todo-list-backend": "1.0.4", + "@internal/plugin-todo-list-common": "1.0.3", + "@backstage/plugin-explore": "0.3.39", + "@backstage/plugin-explore-react": "0.0.20", + "@backstage/plugin-firehydrant": "0.1.25", + "@backstage/plugin-fossa": "0.2.40", + "@backstage/plugin-gcalendar": "0.3.4", + "@backstage/plugin-gcp-projects": "0.3.27", + "@backstage/plugin-git-release-manager": "0.3.21", + "@backstage/plugin-github-actions": "0.5.8", + "@backstage/plugin-github-deployments": "0.1.39", + "@backstage/plugin-github-issues": "0.1.0", + "@backstage/plugin-github-pull-requests-board": "0.1.2", + "@backstage/plugin-gitops-profiles": "0.3.26", + "@backstage/plugin-gocd": "0.1.14", + "@backstage/plugin-graphiql": "0.2.40", + "@backstage/plugin-graphql-backend": "0.1.25", + "@backstage/plugin-home": "0.4.24", + "@backstage/plugin-ilert": "0.1.34", + "@backstage/plugin-jenkins": "0.7.7", + "@backstage/plugin-jenkins-backend": "0.1.25", + "@backstage/plugin-jenkins-common": "0.1.7", + "@backstage/plugin-kafka": "0.3.8", + "@backstage/plugin-kafka-backend": "0.2.28", + "@backstage/plugin-kubernetes": "0.7.1", + "@backstage/plugin-kubernetes-backend": "0.7.1", + "@backstage/plugin-kubernetes-common": "0.4.1", + "@backstage/plugin-lighthouse": "0.3.8", + "@backstage/plugin-newrelic": "0.3.26", + "@backstage/plugin-newrelic-dashboard": "0.2.1", + "@backstage/plugin-org": "0.5.8", + "@backstage/plugin-pagerduty": "0.5.1", + "@backstage/plugin-periskop": "0.1.6", + "@backstage/plugin-periskop-backend": "0.1.6", + "@backstage/plugin-permission-backend": "0.5.10", + "@backstage/plugin-permission-common": "0.6.3", + "@backstage/plugin-permission-node": "0.6.4", + "@backstage/plugin-permission-react": "0.4.4", + "@backstage/plugin-proxy-backend": "0.2.29", + "@backstage/plugin-rollbar": "0.4.8", + "@backstage/plugin-rollbar-backend": "0.1.32", + "@backstage/plugin-scaffolder": "1.5.0", + "@backstage/plugin-scaffolder-backend": "1.5.0", + "@backstage/plugin-scaffolder-backend-module-cookiecutter": "0.2.10", + "@backstage/plugin-scaffolder-backend-module-rails": "0.4.3", + "@backstage/plugin-scaffolder-backend-module-yeoman": "0.2.8", + "@backstage/plugin-scaffolder-common": "1.1.2", + "@backstage/plugin-search": "1.0.1", + "@backstage/plugin-search-backend": "1.0.1", + "@backstage/plugin-search-backend-module-elasticsearch": "1.0.1", + "@backstage/plugin-search-backend-module-pg": "0.3.6", + "@backstage/plugin-search-backend-node": "1.0.1", + "@backstage/plugin-search-common": "1.0.0", + "@backstage/plugin-search-react": "1.0.1", + "@backstage/plugin-sentry": "0.4.1", + "@backstage/plugin-shortcuts": "0.3.0", + "@backstage/plugin-sonarqube": "0.4.0", + "@backstage/plugin-sonarqube-backend": "0.1.0", + "@backstage/plugin-splunk-on-call": "0.3.32", + "@backstage/plugin-stack-overflow": "0.1.4", + "@backstage/plugin-stack-overflow-backend": "0.1.4", + "@backstage/plugin-tech-insights": "0.2.4", + "@backstage/plugin-tech-insights-backend": "0.5.1", + "@backstage/plugin-tech-insights-backend-module-jsonfc": "0.1.19", + "@backstage/plugin-tech-insights-common": "0.2.6", + "@backstage/plugin-tech-insights-node": "0.3.3", + "@backstage/plugin-tech-radar": "0.5.15", + "@backstage/plugin-techdocs": "1.3.1", + "@backstage/plugin-techdocs-addons-test-utils": "1.0.3", + "@backstage/plugin-techdocs-backend": "1.2.1", + "@backstage/plugin-techdocs-module-addons-contrib": "1.0.3", + "@backstage/plugin-techdocs-node": "1.3.0", + "@backstage/plugin-techdocs-react": "1.0.3", + "@backstage/plugin-todo": "0.2.10", + "@backstage/plugin-todo-backend": "0.1.32", + "@backstage/plugin-user-settings": "0.4.7", + "@backstage/plugin-vault": "0.1.2", + "@backstage/plugin-vault-backend": "0.2.1", + "@backstage/plugin-xcmetrics": "0.2.28" }, - "changesets": [ - "afraid-flies-try", - "beige-carpets-double", - "beige-carpets-triple", - "beige-horses-scream", - "beige-kiwis-know", - "blue-monkeys-explain", - "brave-badgers-pump", - "breezy-poems-grab", - "breezy-seas-exist", - "breezy-spiders-eat", - "bright-balloons-hide", - "calm-experts-buy", - "chilled-mirrors-grab", - "cold-coins-tickle", - "cool-toys-flow", - "create-app-1656408352", - "create-app-1657631847", - "cuddly-comics-pump", - "cuddly-flowers-provide", - "curly-candles-battle", - "curvy-weeks-matter", - "eight-suits-fail", - "eighty-windows-brush", - "fifty-cars-compare", - "fifty-vans-drum", - "five-fireants-run", - "forty-seals-complain", - "funny-fireants-shop", - "great-roses-pump", - "green-actors-argue", - "happy-boxes-melt", - "hip-ways-shop", - "hot-rice-sin", - "hungry-cougars-press", - "large-kangaroos-poke", - "lazy-steaks-tell", - "lemon-goats-obey", - "light-hornets-eat", - "little-geckos-end", - "little-guests-sell", - "long-bananas-rescue", - "loud-lemons-listen", - "many-vans-thank", - "mean-adults-argue", - "mean-berries-kick", - "metal-singers-matter", - "metal-windows-share", - "modern-ducks-lay", - "moody-crabs-march", - "nasty-zoos-cross", - "nervous-hounds-matter", - "nervous-humans-sip", - "nice-seas-jam", - "ninety-coats-learn", - "old-onions-hear", - "perfect-donuts-applaud", - "pink-cars-pretend", - "plenty-clouds-guess", - "polite-lions-sell", - "polite-moose-beam", - "popular-pots-yell", - "pretty-masks-live", - "proud-toys-return", - "purple-beans-march", - "purple-cherries-fix", - "quiet-pens-notice", - "red-games-decide", - "renovate-0546761", - "renovate-0cf9337", - "renovate-149779d", - "renovate-2ae4dda", - "renovate-33c3cf4", - "renovate-3aba547", - "renovate-4338117", - "renovate-4b5ff24", - "renovate-7438bff", - "renovate-833a91b", - "renovate-913f3dc", - "renovate-9454dab", - "renovate-9bbb0fb", - "renovate-cbb545a", - "renovate-d26eca1", - "renovate-dc1ee8d", - "renovate-dd35ce8", - "renovate-e091137", - "renovate-f43300b", - "rich-goats-breathe", - "rich-steaks-juggle", - "rude-llamas-lie", - "search-boats-double", - "search-lightning-cult", - "search-turtles-itch", - "serious-houses-watch", - "serious-zebras-joke", - "shaggy-melons-drive", - "shaggy-spiders-notice", - "sharp-numbers-taste", - "sharp-planes-turn", - "shiny-seahorses-do", - "shiny-turkeys-doubt", - "short-deers-remember", - "short-olives-train", - "short-wolves-applaud", - "shy-cameras-develop", - "silent-coats-brake", - "silly-geese-design", - "silver-needles-unite", - "small-shoes-hide", - "smart-elephants-knock", - "smooth-sheep-hide", - "spicy-walls-repair", - "stale-needles-applaud", - "strange-tables-flash", - "strange-trains-collect", - "strong-lies-explain", - "sweet-plants-sparkle", - "swift-plants-fix", - "tame-guests-wave", - "techdocs-eyes-sit", - "techdocs-gorgeous-plants-sniff", - "techdocs-sheep-talk", - "techdocs-sixty-mugs-hug", - "techdocs-the-whole-pulse", - "ten-cobras-wash", - "tender-chicken-learn", - "tender-terms-flash", - "thick-cats-kiss", - "thick-radios-drive", - "thirty-rivers-watch", - "tricky-ravens-visit", - "twelve-candles-jump", - "twelve-peaches-tickle", - "two-crews-accept", - "two-owls-cry", - "unlucky-stingrays-juggle", - "warm-monkeys-study", - "weak-bananas-deliver", - "weak-jeans-cry", - "weak-llamas-repeat", - "wet-cameras-juggle", - "wet-dolphins-act", - "wicked-icons-grin", - "wicked-ladybugs-argue" - ] + "changesets": [] } diff --git a/.changeset/pretty-masks-live.md b/.changeset/pretty-masks-live.md deleted file mode 100644 index c45ad1e77f..0000000000 --- a/.changeset/pretty-masks-live.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-model': patch ---- - -Added type predicates for all entity types, e.g. isUserEntity diff --git a/.changeset/proud-toys-return.md b/.changeset/proud-toys-return.md deleted file mode 100644 index f93e6ef4a8..0000000000 --- a/.changeset/proud-toys-return.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-model': minor ---- - -Introduced `GroupDefaultParentEntityPolicy` to set a default group entity parent. diff --git a/.changeset/purple-beans-march.md b/.changeset/purple-beans-march.md deleted file mode 100644 index f4a3b45ab2..0000000000 --- a/.changeset/purple-beans-march.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Fix `webpack-dev-server` deprecations. diff --git a/.changeset/purple-cherries-fix.md b/.changeset/purple-cherries-fix.md deleted file mode 100644 index d29a107cf3..0000000000 --- a/.changeset/purple-cherries-fix.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -'@backstage/plugin-sentry': minor ---- - -Added the possibility to specify organization per component, now the annotation `sentry.io/project-slug` can have the format of `[organization]/[project-slug]` or just `[project-slug]`. - -**BREAKING**: The method `fetchIssue` changed the signature: - -```diff -export interface SentryApi { - fetchIssues( -- project: string, -- statsFor: string, -- query?: string, -+ entity: Entity, -+ options: { -+ statsFor: string; -+ query?: string; -+ }, - ): Promise; -} -``` diff --git a/.changeset/quiet-pens-notice.md b/.changeset/quiet-pens-notice.md deleted file mode 100644 index aa6aeb049d..0000000000 --- a/.changeset/quiet-pens-notice.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/backend-common': patch ---- - -Improve plural handling in logging output for secrets diff --git a/.changeset/red-games-decide.md b/.changeset/red-games-decide.md deleted file mode 100644 index 208cecfc0a..0000000000 --- a/.changeset/red-games-decide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs-module-protoc-gen-doc': minor ---- - -Added the new `grpcDocsApiWidget` to render `protoc-gen-doc` generated descriptors by the `grpc-docs` package. diff --git a/.changeset/renovate-0546761.md b/.changeset/renovate-0546761.md deleted file mode 100644 index ed7b8b19a3..0000000000 --- a/.changeset/renovate-0546761.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/backend-test-utils': patch -'@backstage/catalog-client': patch -'@backstage/cli': patch -'@backstage/config-loader': patch -'@backstage/core-app-api': patch -'@backstage/core-components': patch -'@backstage/core-plugin-api': patch -'@backstage/integration-react': patch -'@backstage/integration': patch -'@backstage/release-manifests': patch -'@backstage/test-utils': patch -'@backstage/plugin-adr-backend': patch -'@backstage/plugin-adr': patch -'@backstage/plugin-airbrake-backend': patch -'@backstage/plugin-airbrake': patch -'@backstage/plugin-allure': patch -'@backstage/plugin-analytics-module-ga': patch -'@backstage/plugin-apache-airflow': patch -'@backstage/plugin-api-docs': patch -'@backstage/plugin-app-backend': patch -'@backstage/plugin-auth-backend': patch -'@backstage/plugin-auth-node': patch -'@backstage/plugin-azure-devops-backend': patch -'@backstage/plugin-azure-devops': patch -'@backstage/plugin-badges': patch -'@backstage/plugin-bitbucket-cloud-common': patch -'@backstage/plugin-bitrise': patch -'@backstage/plugin-catalog-backend-module-azure': patch -'@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch -'@backstage/plugin-catalog-backend-module-bitbucket': patch -'@backstage/plugin-catalog-backend-module-gerrit': patch -'@backstage/plugin-catalog-backend-module-github': patch -'@backstage/plugin-catalog-backend-module-gitlab': patch -'@backstage/plugin-catalog-backend-module-msgraph': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-catalog-graphql': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-circleci': patch -'@backstage/plugin-cloudbuild': patch -'@backstage/plugin-code-climate': patch -'@backstage/plugin-code-coverage-backend': patch -'@backstage/plugin-code-coverage': patch -'@backstage/plugin-codescene': patch -'@backstage/plugin-config-schema': patch -'@backstage/plugin-cost-insights': patch -'@backstage/plugin-dynatrace': patch -'@backstage/plugin-explore-react': patch -'@backstage/plugin-explore': patch -'@backstage/plugin-firehydrant': patch -'@backstage/plugin-fossa': patch -'@backstage/plugin-gcalendar': patch -'@backstage/plugin-gcp-projects': patch -'@backstage/plugin-git-release-manager': patch -'@backstage/plugin-github-actions': patch -'@backstage/plugin-github-deployments': patch -'@backstage/plugin-github-pull-requests-board': patch -'@backstage/plugin-gitops-profiles': patch -'@backstage/plugin-gocd': patch -'@backstage/plugin-graphiql': patch -'@backstage/plugin-graphql-backend': patch -'@backstage/plugin-home': patch -'@backstage/plugin-ilert': patch -'@backstage/plugin-jenkins-backend': patch -'@backstage/plugin-jenkins': patch -'@backstage/plugin-kafka': patch -'@backstage/plugin-kubernetes': patch -'@backstage/plugin-lighthouse': patch -'@backstage/plugin-newrelic': patch -'@backstage/plugin-org': patch -'@backstage/plugin-pagerduty': patch -'@backstage/plugin-periskop-backend': patch -'@backstage/plugin-periskop': patch -'@backstage/plugin-permission-backend': patch -'@backstage/plugin-permission-common': patch -'@backstage/plugin-permission-node': patch -'@backstage/plugin-rollbar-backend': patch -'@backstage/plugin-rollbar': patch -'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-search': patch -'@backstage/plugin-sentry': patch -'@backstage/plugin-shortcuts': patch -'@backstage/plugin-sonarqube': patch -'@backstage/plugin-splunk-on-call': patch -'@backstage/plugin-stack-overflow': patch -'@backstage/plugin-tech-insights': patch -'@backstage/plugin-tech-radar': patch -'@backstage/plugin-techdocs-addons-test-utils': patch -'@backstage/plugin-techdocs-backend': patch -'@backstage/plugin-techdocs-module-addons-contrib': patch -'@backstage/plugin-techdocs': patch -'@backstage/plugin-todo-backend': patch -'@backstage/plugin-todo': patch -'@backstage/plugin-user-settings': patch -'@backstage/plugin-vault-backend': patch -'@backstage/plugin-vault': patch -'@backstage/plugin-xcmetrics': patch ---- - -Updated dependency `msw` to `^0.43.0`. diff --git a/.changeset/renovate-0cf9337.md b/.changeset/renovate-0cf9337.md deleted file mode 100644 index 8544c10b50..0000000000 --- a/.changeset/renovate-0cf9337.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/backend-tasks': patch -'@backstage/integration': patch -'@backstage/plugin-adr-backend': patch -'@backstage/plugin-app-backend': patch -'@backstage/plugin-auth-backend': patch -'@backstage/plugin-azure-devops': patch -'@backstage/plugin-bazaar': patch -'@backstage/plugin-bitrise': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-cicd-statistics-module-gitlab': patch -'@backstage/plugin-cicd-statistics': patch -'@backstage/plugin-circleci': patch -'@backstage/plugin-cloudbuild': patch -'@backstage/plugin-code-climate': patch -'@backstage/plugin-code-coverage': patch -'@backstage/plugin-cost-insights': patch -'@backstage/plugin-firehydrant': patch -'@backstage/plugin-fossa': patch -'@backstage/plugin-gcalendar': patch -'@backstage/plugin-git-release-manager': patch -'@backstage/plugin-github-actions': patch -'@backstage/plugin-github-deployments': patch -'@backstage/plugin-gocd': patch -'@backstage/plugin-ilert': patch -'@backstage/plugin-jenkins': patch -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-kubernetes': patch -'@backstage/plugin-pagerduty': patch -'@backstage/plugin-periskop': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-sentry': patch -'@backstage/plugin-splunk-on-call': patch -'@backstage/plugin-tech-insights-backend-module-jsonfc': patch -'@backstage/plugin-tech-insights-backend': patch -'@backstage/plugin-tech-insights-common': patch -'@backstage/plugin-tech-insights-node': patch -'@backstage/plugin-xcmetrics': patch ---- - -Updated dependency `luxon` to `^3.0.0`. diff --git a/.changeset/renovate-149779d.md b/.changeset/renovate-149779d.md deleted file mode 100644 index 58d764485e..0000000000 --- a/.changeset/renovate-149779d.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-kafka-backend': patch ---- - -Updated dependency `kafkajs` to `^2.0.0`. diff --git a/.changeset/renovate-2ae4dda.md b/.changeset/renovate-2ae4dda.md deleted file mode 100644 index 2cedbcb9d7..0000000000 --- a/.changeset/renovate-2ae4dda.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-openapi': patch ---- - -Updated dependency `openapi-types` to `^12.0.0`. diff --git a/.changeset/renovate-33c3cf4.md b/.changeset/renovate-33c3cf4.md deleted file mode 100644 index 8389a89ea1..0000000000 --- a/.changeset/renovate-33c3cf4.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/catalog-model': patch -'@backstage/cli': patch -'@backstage/config-loader': patch -'@backstage/plugin-catalog-backend-module-aws': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-catalog-react': patch -'@backstage/plugin-proxy-backend': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-scaffolder': patch ---- - -Updated dependency `yaml` to `^2.0.0`. diff --git a/.changeset/renovate-3aba547.md b/.changeset/renovate-3aba547.md deleted file mode 100644 index 61b67f74ab..0000000000 --- a/.changeset/renovate-3aba547.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-github': patch -'@backstage/plugin-github-deployments': patch ---- - -Updated dependency `@octokit/graphql` to `^5.0.0`. diff --git a/.changeset/renovate-4338117.md b/.changeset/renovate-4338117.md deleted file mode 100644 index 199073c599..0000000000 --- a/.changeset/renovate-4338117.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/core-components': patch -'@backstage/plugin-gcp-projects': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-techdocs-module-addons-contrib': patch ---- - -Updated dependency `@react-hookz/web` to `^15.0.0`. diff --git a/.changeset/renovate-4b5ff24.md b/.changeset/renovate-4b5ff24.md deleted file mode 100644 index 4867c345d8..0000000000 --- a/.changeset/renovate-4b5ff24.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependency `run-script-webpack-plugin` to `^0.1.0`. diff --git a/.changeset/renovate-7438bff.md b/.changeset/renovate-7438bff.md deleted file mode 100644 index 43a4ac5016..0000000000 --- a/.changeset/renovate-7438bff.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/backend-tasks': patch -'@backstage/backend-test-utils': patch -'@backstage/plugin-app-backend': patch -'@backstage/plugin-auth-backend': patch -'@backstage/plugin-bazaar-backend': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-code-coverage-backend': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-search-backend-module-pg': patch -'@backstage/plugin-tech-insights-backend': patch -'@backstage/plugin-techdocs-backend': patch ---- - -Updated dependency `knex` to `^2.0.0`. diff --git a/.changeset/renovate-7d3b357.md b/.changeset/renovate-7d3b357.md new file mode 100644 index 0000000000..bdb86d12c2 --- /dev/null +++ b/.changeset/renovate-7d3b357.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': patch +--- + +Updated dependency `json-schema-library` to `^7.0.0`. diff --git a/.changeset/renovate-833a91b.md b/.changeset/renovate-833a91b.md deleted file mode 100644 index 15e23ec5ff..0000000000 --- a/.changeset/renovate-833a91b.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/core-components': patch -'@backstage/plugin-codescene': patch -'@backstage/plugin-sonarqube': patch ---- - -Updated dependency `rc-progress` to `3.4.0`. diff --git a/.changeset/renovate-913f3dc.md b/.changeset/renovate-913f3dc.md deleted file mode 100644 index edb2f95356..0000000000 --- a/.changeset/renovate-913f3dc.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/config-loader': patch ---- - -Updated dependency `typescript-json-schema` to `^0.54.0`. diff --git a/.changeset/renovate-9454dab.md b/.changeset/renovate-9454dab.md deleted file mode 100644 index 1f8401e10f..0000000000 --- a/.changeset/renovate-9454dab.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Updated dependency `google-auth-library` to `^8.0.0`. diff --git a/.changeset/renovate-9ad149b.md b/.changeset/renovate-9ad149b.md deleted file mode 100644 index aa4baa3dd1..0000000000 --- a/.changeset/renovate-9ad149b.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependency `@spotify/prettier-config` to `^14.0.0`. -Updated dependency `@spotify/eslint-config-base` to `^14.0.0`. -Updated dependency `@spotify/eslint-config-react` to `^14.0.0`. -Updated dependency `@spotify/eslint-config-typescript` to `^14.0.0`. diff --git a/.changeset/renovate-9bbb0fb.md b/.changeset/renovate-9bbb0fb.md deleted file mode 100644 index 1e122fb43f..0000000000 --- a/.changeset/renovate-9bbb0fb.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -Updated dependency `@octokit/request` to `^6.0.0`. diff --git a/.changeset/renovate-6403cb0.md b/.changeset/renovate-c98c336.md similarity index 94% rename from .changeset/renovate-6403cb0.md rename to .changeset/renovate-c98c336.md index 817d409f51..b2139cfe20 100644 --- a/.changeset/renovate-6403cb0.md +++ b/.changeset/renovate-c98c336.md @@ -19,6 +19,7 @@ '@backstage/plugin-analytics-module-ga': patch '@backstage/plugin-apache-airflow': patch '@backstage/plugin-api-docs': patch +'@backstage/plugin-apollo-explorer': patch '@backstage/plugin-app-backend': patch '@backstage/plugin-auth-backend': patch '@backstage/plugin-auth-node': patch @@ -29,6 +30,7 @@ '@backstage/plugin-bitrise': patch '@backstage/plugin-catalog-backend-module-azure': patch '@backstage/plugin-catalog-backend-module-bitbucket-cloud': patch +'@backstage/plugin-catalog-backend-module-bitbucket-server': patch '@backstage/plugin-catalog-backend-module-bitbucket': patch '@backstage/plugin-catalog-backend-module-gerrit': patch '@backstage/plugin-catalog-backend-module-github': patch @@ -55,6 +57,7 @@ '@backstage/plugin-git-release-manager': patch '@backstage/plugin-github-actions': patch '@backstage/plugin-github-deployments': patch +'@backstage/plugin-github-issues': patch '@backstage/plugin-github-pull-requests-board': patch '@backstage/plugin-gitops-profiles': patch '@backstage/plugin-gocd': patch @@ -84,6 +87,7 @@ '@backstage/plugin-search': patch '@backstage/plugin-sentry': patch '@backstage/plugin-shortcuts': patch +'@backstage/plugin-sonarqube-backend': patch '@backstage/plugin-sonarqube': patch '@backstage/plugin-splunk-on-call': patch '@backstage/plugin-stack-overflow': patch @@ -101,4 +105,4 @@ '@backstage/plugin-xcmetrics': patch --- -Updated dependency `msw` to `^0.44.0`. +Updated dependency `msw` to `^0.45.0`. diff --git a/.changeset/renovate-cbb545a.md b/.changeset/renovate-cbb545a.md deleted file mode 100644 index be423e8252..0000000000 --- a/.changeset/renovate-cbb545a.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Updated dependency `@asyncapi/react-component` to `1.0.0-next.39`. diff --git a/.changeset/renovate-d26eca1.md b/.changeset/renovate-d26eca1.md deleted file mode 100644 index 6ddad0d5fe..0000000000 --- a/.changeset/renovate-d26eca1.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-adr': patch -'@backstage/plugin-scaffolder-backend': patch ---- - -Updated dependency `octokit` to `^2.0.0`. diff --git a/.changeset/renovate-dc1ee8d.md b/.changeset/renovate-dc1ee8d.md deleted file mode 100644 index a6f87f5484..0000000000 --- a/.changeset/renovate-dc1ee8d.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-elasticsearch': patch ---- - -Updated dependency `@opensearch-project/opensearch` to `^2.0.0`. diff --git a/.changeset/renovate-dd35ce8.md b/.changeset/renovate-dd35ce8.md deleted file mode 100644 index 9d828bc42d..0000000000 --- a/.changeset/renovate-dd35ce8.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': patch -'@backstage/plugin-kubernetes-common': patch -'@backstage/plugin-kubernetes': patch ---- - -Updated dependency `@kubernetes/client-node` to `^0.17.0`. diff --git a/.changeset/renovate-e091137.md b/.changeset/renovate-e091137.md deleted file mode 100644 index a5f53a1ec5..0000000000 --- a/.changeset/renovate-e091137.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Updated dependency `@octokit/webhooks` to `^10.0.0`. diff --git a/.changeset/renovate-f43300b.md b/.changeset/renovate-f43300b.md deleted file mode 100644 index 78f327c8b3..0000000000 --- a/.changeset/renovate-f43300b.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/integration': patch ---- - -Updated dependency `@octokit/auth-app` to `^4.0.0`. diff --git a/.changeset/rich-goats-breathe.md b/.changeset/rich-goats-breathe.md deleted file mode 100644 index 2888c2f9a7..0000000000 --- a/.changeset/rich-goats-breathe.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-tech-insights-backend': minor ---- - -**BREAKING**: Update FactRetrieverRegistry interface to be async so that db backed implementations can be passed through to the FactRetrieverEngine. - -If you have existing custom `FactRetrieverRegistry` implementations, you'll need to remove the `retrievers` member and make all the methods async. diff --git a/.changeset/rich-steaks-juggle.md b/.changeset/rich-steaks-juggle.md deleted file mode 100644 index 5879f2dace..0000000000 --- a/.changeset/rich-steaks-juggle.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-tech-insights-node': patch -'@backstage/plugin-tech-insights-backend': patch ---- - -The `FactRetriever` model has been extended by adding optional title and description fields, allowing you to display them in the UI. diff --git a/.changeset/rude-books-rush.md b/.changeset/rude-books-rush.md new file mode 100644 index 0000000000..a98e90e27e --- /dev/null +++ b/.changeset/rude-books-rush.md @@ -0,0 +1,9 @@ +--- +'@backstage/backend-tasks': patch +'@backstage/plugin-app-backend': patch +'@backstage/plugin-bazaar-backend': patch +'@backstage/plugin-code-coverage-backend': patch +'@backstage/plugin-tech-insights-backend': patch +--- + +Fixed a bug where the database option to skip migrations was ignored. diff --git a/.changeset/rude-llamas-lie.md b/.changeset/rude-llamas-lie.md deleted file mode 100644 index 918d61da6d..0000000000 --- a/.changeset/rude-llamas-lie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-vault': patch ---- - -Export missing parameters and added them to the api-report. Also adapted the API to the expected response from the backend diff --git a/.changeset/search-boats-double.md b/.changeset/search-boats-double.md deleted file mode 100644 index 92fd372cb8..0000000000 --- a/.changeset/search-boats-double.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-react': patch ---- - -Fix search pagination to reset page cursor also when a term is cleared. diff --git a/.changeset/search-lightning-cult.md b/.changeset/search-lightning-cult.md deleted file mode 100644 index 79cd256e77..0000000000 --- a/.changeset/search-lightning-cult.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-elasticsearch': minor ---- - -**BREAKING**: In order to remain interoperable with all currently supported -deployments of Elasticsearch, this package will now conditionally use either -the `@elastic/elasticsearch` or `@opensearch-project/opensearch` client when -communicating with your deployed cluster. - -If you do not rely on types exported from this package, or if you do not make -use of the `createElasticSearchClientOptions` or `newClient` methods on the -`ElasticSearchSearchEngine` class, then upgrading to this version should not -require any further action on your part. Everything will continue to work as it -always has. - -If you _do_ rely on either of the above methods or any underlying types, some -changes may be needed to your custom code. A type guard is now exported by this -package (`isOpenSearchCompatible(options)`), which you may use to help clarify -which client options are compatible with which client constructors. - -If you are using this package with the `search.elasticsearch.provider` set to -`aws`, and you are making use of the `newClient` method in particular, you may -wish to start using the `@opensearch-project/opensearch` client in your custom -code. diff --git a/.changeset/search-turtles-itch.md b/.changeset/search-turtles-itch.md deleted file mode 100644 index 2da26fc64a..0000000000 --- a/.changeset/search-turtles-itch.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -'@backstage/plugin-search': patch ---- - -To allow people to use a global search context in the search modal, the code for the search modal has been changed to only create a local search context if there is no parent context already defined. - -If you want to continue using a local context even if you define a global one, you will have to wrap the modal in a new local context manually: - -```tsx - - - -``` diff --git a/.changeset/serious-houses-watch.md b/.changeset/serious-houses-watch.md deleted file mode 100644 index 63d5253bcb..0000000000 --- a/.changeset/serious-houses-watch.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/theme': patch ---- - -**DEPRECATED**: The `bursts` object from `BackstagePaletteAdditions` has been depreciated and will be removed in a future release - -The `genPageTheme` function now includes an optional options object with an optional `fontColor` which defaults to white if not provided. diff --git a/.changeset/serious-zebras-joke.md b/.changeset/serious-zebras-joke.md deleted file mode 100644 index 78f38ca967..0000000000 --- a/.changeset/serious-zebras-joke.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Support displaying subtitle text in `SidebarSubmenuItem` diff --git a/.changeset/shaggy-melons-drive.md b/.changeset/shaggy-melons-drive.md deleted file mode 100644 index b5674493f4..0000000000 --- a/.changeset/shaggy-melons-drive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/catalog-model': minor ---- - -Adding an optional type field to entity links to group and categorize links diff --git a/.changeset/shaggy-spiders-notice.md b/.changeset/shaggy-spiders-notice.md deleted file mode 100644 index 513f6cd521..0000000000 --- a/.changeset/shaggy-spiders-notice.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -CatalogBuilder supports now subscription to processing engine errors. - -```ts -subscribe(options: { - onProcessingError: (event: { unprocessedEntity: Entity, error: Error }) => Promise | void; -}); -``` - -If you want to get notified on errors while processing the entities, you call CatalogBuilder.subscribe -to get notifications with the parameters defined as above. diff --git a/.changeset/sharp-numbers-taste.md b/.changeset/sharp-numbers-taste.md deleted file mode 100644 index 4819aca18f..0000000000 --- a/.changeset/sharp-numbers-taste.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/errors': minor ---- - -The `ResponseError.fromResponse` now accepts a more narrow response type, in order to avoid incompatibilities between different fetch implementations. - -The `response` property of `ResponseError` has also been narrowed to a new `ConsumedResponse` type that omits all the properties for consuming the body of the response. This is not considered a breaking change as it was always an error to try to consume the body of the response. diff --git a/.changeset/sharp-planes-turn.md b/.changeset/sharp-planes-turn.md deleted file mode 100644 index 47f6a6176d..0000000000 --- a/.changeset/sharp-planes-turn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-vault-backend': minor ---- - -Throw exceptions instead of swallow them, remove some exported types from the `api-report`, small changes in the API responses & expose the vault `baseUrl` to the frontend as well diff --git a/.changeset/sharp-swans-suffer.md b/.changeset/sharp-swans-suffer.md new file mode 100644 index 0000000000..841d746634 --- /dev/null +++ b/.changeset/sharp-swans-suffer.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +Added support for `async` validation for the `next` version of the plugin diff --git a/.changeset/shiny-lobsters-fix.md b/.changeset/shiny-lobsters-fix.md new file mode 100644 index 0000000000..99e255acbe --- /dev/null +++ b/.changeset/shiny-lobsters-fix.md @@ -0,0 +1,39 @@ +--- +'@backstage/plugin-azure-devops-backend': patch +--- + +`createRouter` now requires an additional reader: `UrlReader` argument + +```diff +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return createRouter({ + logger: env.logger, + config: env.config, ++ reader: env.reader, + }); +} +``` + +Remember to check if you have already provided these settings previously. + +#### [Azure DevOps] + +```yaml +# app-config.yaml +azureDevOps: + host: dev.azure.com + token: my-token + organization: my-company +``` + +#### [Azure Integrations] + +```yaml +# app-config.yaml +integrations: + azure: + - host: dev.azure.com + token: ${AZURE_TOKEN} +``` diff --git a/.changeset/shiny-seahorses-do.md b/.changeset/shiny-seahorses-do.md deleted file mode 100644 index 06892900bf..0000000000 --- a/.changeset/shiny-seahorses-do.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-badges-backend': patch ---- - -Add missing installation instructions diff --git a/.changeset/shiny-turkeys-doubt.md b/.changeset/shiny-turkeys-doubt.md deleted file mode 100644 index edac39182c..0000000000 --- a/.changeset/shiny-turkeys-doubt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-org': patch ---- - -Render namespaces for teams with subtitles in `MyGroupsSidebarItem` diff --git a/.changeset/short-deers-remember.md b/.changeset/short-deers-remember.md deleted file mode 100644 index 7579e7773b..0000000000 --- a/.changeset/short-deers-remember.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/integration': patch -'@backstage/plugin-adr': patch -'@backstage/plugin-catalog-backend': patch -'@backstage/plugin-catalog-import': patch -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-scaffolder-backend': patch -'@backstage/plugin-techdocs': patch -'@backstage/plugin-techdocs-module-addons-contrib': patch -'@backstage/plugin-techdocs-node': patch ---- - -Upgrade git-url-parse to 12.0.0. - -Motivation for upgrade is transitively upgrading parse-url which is vulnerable -to several CVEs detected by Snyk. - -- SNYK-JS-PARSEURL-2935944 -- SNYK-JS-PARSEURL-2935947 -- SNYK-JS-PARSEURL-2936249 diff --git a/.changeset/short-olives-train.md b/.changeset/short-olives-train.md deleted file mode 100644 index 594d95f073..0000000000 --- a/.changeset/short-olives-train.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-kubernetes-backend': minor -'@backstage/plugin-kubernetes-common': minor ---- - -Refactor `KubernetesObjectsProvider` with new methods, `KubernetesServiceLocator` now takes an `Entity` instead of `serviceId` diff --git a/.changeset/short-wolves-applaud.md b/.changeset/short-wolves-applaud.md deleted file mode 100644 index fa5cebffc3..0000000000 --- a/.changeset/short-wolves-applaud.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor ---- - -Export experimental `scaffolderCatalogExtension` for the new backend system. This export is not considered stable and should not be used in production. diff --git a/.changeset/shy-cameras-develop.md b/.changeset/shy-cameras-develop.md deleted file mode 100644 index c62a9a56e3..0000000000 --- a/.changeset/shy-cameras-develop.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-openapi': minor ---- - -Add basic OpenAPI \$ref support. - -For more information see [here](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend-module-openapi). diff --git a/.changeset/silent-coats-brake.md b/.changeset/silent-coats-brake.md deleted file mode 100644 index b1cfbacb6a..0000000000 --- a/.changeset/silent-coats-brake.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-catalog': patch -'@backstage/plugin-catalog-backend': patch ---- - -Use entity type predicates from catalog-model diff --git a/.changeset/silent-kings-live.md b/.changeset/silent-kings-live.md new file mode 100644 index 0000000000..7e55f5ae78 --- /dev/null +++ b/.changeset/silent-kings-live.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder-backend': patch +--- + +Removed the depreacated `publish:file` action, use the template editor to test templates instead. diff --git a/.changeset/silly-geese-design.md b/.changeset/silly-geese-design.md deleted file mode 100644 index d4f8de2510..0000000000 --- a/.changeset/silly-geese-design.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch -'@backstage/plugin-catalog': minor ---- - -Add hidden title column to catalog and API table to enable filtering by title. diff --git a/.changeset/silver-needles-unite.md b/.changeset/silver-needles-unite.md deleted file mode 100644 index b5fed7e615..0000000000 --- a/.changeset/silver-needles-unite.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -'@backstage/plugin-home': patch ---- - -Added support for customizing the time format used in the `HeaderWorldClock` component - -Here's an example of how this can be used in the `HomePage.tsx` found in `\packages\app\src\components\home` to change the clock to be in the 24hr time format: - -```diff -+const timeFormat: Intl.DateTimeFormatOptions = { -+ hour: '2-digit', -+ minute: '2-digit', -+ hour12: false, -+}; - -export const homePage = ( - -
} pageTitleOverride="Home"> -+ -
- - - - - -``` diff --git a/.changeset/slimy-zebras-reply.md b/.changeset/slimy-zebras-reply.md new file mode 100644 index 0000000000..5b309f5129 --- /dev/null +++ b/.changeset/slimy-zebras-reply.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-ldap': patch +--- + +Now the `searchStream` method in LDAP client awaits the callbacks diff --git a/.changeset/small-shoes-hide.md b/.changeset/small-shoes-hide.md deleted file mode 100644 index b1f95e9f2d..0000000000 --- a/.changeset/small-shoes-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend-node': patch ---- - -Exports `MissingIndexError` that can be used by the search engines for better error handling when missing index. diff --git a/.changeset/smart-elephants-knock.md b/.changeset/smart-elephants-knock.md deleted file mode 100644 index 7aed10a71e..0000000000 --- a/.changeset/smart-elephants-knock.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/cli': patch ---- - -The `test` command now ensures that all IO is flushed before exiting when printing `--help`. diff --git a/.changeset/smooth-sheep-hide.md b/.changeset/smooth-sheep-hide.md deleted file mode 100644 index 8a65602ca9..0000000000 --- a/.changeset/smooth-sheep-hide.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-devops': patch ---- - -Exporting azureDevOpsApiRef, AzureGitTagsIcon, and all hooks for the benefit of other plugins. diff --git a/.changeset/spicy-cherries-remember.md b/.changeset/spicy-cherries-remember.md new file mode 100644 index 0000000000..c742c7a1e8 --- /dev/null +++ b/.changeset/spicy-cherries-remember.md @@ -0,0 +1,7 @@ +--- +'@backstage/backend-app-api': patch +'@backstage/backend-defaults': patch +'@backstage/backend-test-utils': patch +--- + +Updated usages of `ServiceFactory`. diff --git a/.changeset/spicy-walls-repair.md b/.changeset/spicy-walls-repair.md deleted file mode 100644 index 36187600c7..0000000000 --- a/.changeset/spicy-walls-repair.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': patch ---- - -Add new config option for okta auth server and IDP diff --git a/.changeset/stale-needles-applaud.md b/.changeset/stale-needles-applaud.md deleted file mode 100644 index cc46dc2e3f..0000000000 --- a/.changeset/stale-needles-applaud.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-api-docs': patch ---- - -Set font colors correctly for descriptions containing HTML diff --git a/.changeset/strange-tables-flash.md b/.changeset/strange-tables-flash.md deleted file mode 100644 index b42069aa64..0000000000 --- a/.changeset/strange-tables-flash.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-stack-overflow': patch -'@backstage/plugin-stack-overflow-backend': patch ---- - -app-config is now picked up properly. diff --git a/.changeset/strange-trains-collect.md b/.changeset/strange-trains-collect.md deleted file mode 100644 index 3da9aff515..0000000000 --- a/.changeset/strange-trains-collect.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -The max content size for dry-run files has been reduced from 256k to 64k. diff --git a/.changeset/strong-games-kiss.md b/.changeset/strong-games-kiss.md new file mode 100644 index 0000000000..a5f6d5f864 --- /dev/null +++ b/.changeset/strong-games-kiss.md @@ -0,0 +1,6 @@ +--- +'@backstage/plugin-catalog-backend': patch +'@backstage/plugin-catalog-node': patch +--- + +The experimental `CatalogProcessingExtensionPoint` now accepts multiple providers and processors at once. diff --git a/.changeset/strong-lies-explain.md b/.changeset/strong-lies-explain.md deleted file mode 100644 index d9657be6b4..0000000000 --- a/.changeset/strong-lies-explain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/theme': patch ---- - -Adds optional `htmlFontSize` property and also sets typography design tokens for h5 and h6 in base theme. diff --git a/.changeset/sweet-plants-sparkle.md b/.changeset/sweet-plants-sparkle.md deleted file mode 100644 index 69e7647849..0000000000 --- a/.changeset/sweet-plants-sparkle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/integration': patch ---- - -Allow frontend visibility for `integrations` itself. diff --git a/.changeset/sweet-rats-invite.md b/.changeset/sweet-rats-invite.md deleted file mode 100644 index f292e7bb43..0000000000 --- a/.changeset/sweet-rats-invite.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': patch ---- - -Add sourcePath option to publish:gerrit action diff --git a/.changeset/swift-plants-fix.md b/.changeset/swift-plants-fix.md deleted file mode 100644 index 52873b7985..0000000000 --- a/.changeset/swift-plants-fix.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/backend-app-api': minor ---- - -Add initial plumbing for creating backends using the experimental backend framework. - -This package is highly **EXPERIMENTAL** and should not be used in production. diff --git a/.changeset/tall-pants-clap.md b/.changeset/tall-pants-clap.md deleted file mode 100644 index 5a1714c106..0000000000 --- a/.changeset/tall-pants-clap.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/backend-common': patch -'@backstage/integration': patch ---- - -Support self-hosted gitlab installations with relative URL. diff --git a/.changeset/tame-guests-wave.md b/.changeset/tame-guests-wave.md deleted file mode 100644 index bbf757084d..0000000000 --- a/.changeset/tame-guests-wave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-azure-devops-backend': patch ---- - -Added comments to example to help avoid confusion as to where lines need to be added diff --git a/.changeset/tame-papayas-protect.md b/.changeset/tame-papayas-protect.md new file mode 100644 index 0000000000..9a0266748a --- /dev/null +++ b/.changeset/tame-papayas-protect.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +When defining a new `ServiceRef` you can now also include a `defaultFactory`, which will be used to construct instances of the service in case there is no explicit factory defined. diff --git a/.changeset/techdocs-eyes-sit.md b/.changeset/techdocs-eyes-sit.md deleted file mode 100644 index a09410a4fb..0000000000 --- a/.changeset/techdocs-eyes-sit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-backend': patch ---- - -Add sample headings on the documented component homepage. diff --git a/.changeset/techdocs-gorgeous-plants-sniff.md b/.changeset/techdocs-gorgeous-plants-sniff.md deleted file mode 100644 index f5453f35be..0000000000 --- a/.changeset/techdocs-gorgeous-plants-sniff.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Reorder browser tab title in Techdocs pages to have the site name first. diff --git a/.changeset/techdocs-jeans-wait.md b/.changeset/techdocs-jeans-wait.md new file mode 100644 index 0000000000..b4d9007754 --- /dev/null +++ b/.changeset/techdocs-jeans-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-techdocs': patch +--- + +Always update the title and sub-title when the location changes on a `TechDocs` reader page. diff --git a/.changeset/techdocs-sheep-talk.md b/.changeset/techdocs-sheep-talk.md deleted file mode 100644 index b17408d7a4..0000000000 --- a/.changeset/techdocs-sheep-talk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Remove the 60% factor from the font size calculation of headers to use the exact size defined in BackstageTheme. diff --git a/.changeset/techdocs-sixty-mugs-hug.md b/.changeset/techdocs-sixty-mugs-hug.md deleted file mode 100644 index a1a9e815a1..0000000000 --- a/.changeset/techdocs-sixty-mugs-hug.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs': patch ---- - -Fix: When docs are shown in an entity page under the docs tab the sidebars start overlapping with the header and tabs in the page when you scroll the documentation content. diff --git a/.changeset/techdocs-the-whole-pulse.md b/.changeset/techdocs-the-whole-pulse.md deleted file mode 100644 index b54fb080ae..0000000000 --- a/.changeset/techdocs-the-whole-pulse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@techdocs/cli': patch ---- - -Fixed a bug that prevented docker images from being pulled by default when generating TechDocs. diff --git a/.changeset/ten-cobras-wash.md b/.changeset/ten-cobras-wash.md deleted file mode 100644 index 81915d958d..0000000000 --- a/.changeset/ten-cobras-wash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-auth-backend': minor ---- - -Allowed post method on /refresh path diff --git a/.changeset/tender-chicken-learn.md b/.changeset/tender-chicken-learn.md deleted file mode 100644 index bd95c5545f..0000000000 --- a/.changeset/tender-chicken-learn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend': patch ---- - -If error is `MissingIndexError` we return a 400 response with a more clear error message. diff --git a/.changeset/tender-cycles-shout.md b/.changeset/tender-cycles-shout.md deleted file mode 100644 index b5b069759f..0000000000 --- a/.changeset/tender-cycles-shout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-components': patch ---- - -Improve accessibility for CopyTextButton diff --git a/.changeset/tender-terms-flash.md b/.changeset/tender-terms-flash.md deleted file mode 100644 index ca5fdb3799..0000000000 --- a/.changeset/tender-terms-flash.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/integration': patch ---- - -Avoid double encoding of the file path in `getBitbucketServerDownloadUrl` diff --git a/.changeset/thick-cats-kiss.md b/.changeset/thick-cats-kiss.md deleted file mode 100644 index 8817115ec3..0000000000 --- a/.changeset/thick-cats-kiss.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@backstage/plugin-catalog': patch ---- - -Adding ability to customize the "unregister entity" menu item in the entity context menu on the entity page with options 'visible','hidden','disabled'.With this three new options, one can hide the "unregister entity" menu item from the list, disable or keep it enabled. - -The boolean input for "unregister entity" will be deprecated later in favour of the above three options. diff --git a/.changeset/thick-radios-drive.md b/.changeset/thick-radios-drive.md deleted file mode 100644 index 130030be59..0000000000 --- a/.changeset/thick-radios-drive.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-adr': patch ---- - -Track discover event and result rank for `AdrSearchResultListItem` diff --git a/.changeset/thick-shrimps-hammer.md b/.changeset/thick-shrimps-hammer.md deleted file mode 100644 index ddc0928154..0000000000 --- a/.changeset/thick-shrimps-hammer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': minor ---- - -Add support for `allowedOwners` to the `BitbucketRepoPicker` used for the workspace value. diff --git a/.changeset/thirty-rivers-watch.md b/.changeset/thirty-rivers-watch.md deleted file mode 100644 index d92343f365..0000000000 --- a/.changeset/thirty-rivers-watch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder-backend': minor ---- - -Added two new scaffolder actions: `github:repo:create` and `github:repo:push` diff --git a/.changeset/tough-dolphins-smile.md b/.changeset/tough-dolphins-smile.md new file mode 100644 index 0000000000..bb4f0a39a8 --- /dev/null +++ b/.changeset/tough-dolphins-smile.md @@ -0,0 +1,19 @@ +--- +'@backstage/catalog-client': patch +'@backstage/core-plugin-api': patch +'@backstage/plugin-api-docs': patch +'@backstage/plugin-apollo-explorer': patch +'@backstage/plugin-azure-devops-backend': patch +'@backstage/plugin-badges': patch +'@backstage/plugin-badges-backend': patch +'@backstage/plugin-catalog-react': patch +'@backstage/plugin-circleci': patch +'@backstage/plugin-cloudbuild': patch +'@backstage/plugin-kubernetes': patch +'@backstage/plugin-scaffolder-backend': patch +'@backstage/plugin-search-backend-module-elasticsearch': patch +'@backstage/plugin-sonarqube-backend': patch +'@backstage/plugin-techdocs': patch +--- + +Minor API signatures cleanup diff --git a/.changeset/tricky-ravens-visit.md b/.changeset/tricky-ravens-visit.md deleted file mode 100644 index 8500c9b64e..0000000000 --- a/.changeset/tricky-ravens-visit.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/core-components': patch -'@backstage/plugin-catalog': patch ---- - -Updated to remove usage of the `bursts` object in the theme palette diff --git a/.changeset/twelve-candles-jump.md b/.changeset/twelve-candles-jump.md deleted file mode 100644 index 9d0cccd0ba..0000000000 --- a/.changeset/twelve-candles-jump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-ldap': patch ---- - -Add possibility to resolve relations by RDN, in addition to UUID and DN diff --git a/.changeset/twelve-peaches-tickle.md b/.changeset/twelve-peaches-tickle.md deleted file mode 100644 index 2a7814ea06..0000000000 --- a/.changeset/twelve-peaches-tickle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-backend': patch ---- - -Many symbol declarations have been moved to `@backstage/plugin-catalog-node`. This has no affect on users of this package as they are all re-exported. Modules that build on top of the catalog backend plugin should switch all of their imports to the `@backstage/plugin-catalog-node` package and remove the dependency on `@backstage/plugin-catalog-backend`. diff --git a/.changeset/two-crews-accept.md b/.changeset/two-crews-accept.md deleted file mode 100644 index 9540f97cb5..0000000000 --- a/.changeset/two-crews-accept.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -'@backstage/plugin-catalog-backend-module-gitlab': patch ---- - -Add the possibility in the `GitlabDiscoveryEntityProvider` to scan the whole project instead of concrete groups. For that, use a configuration like this one, where the group parameter is omitted (not mandatory anymore): - -```yaml -catalog: - providers: - gitlab: - yourProviderId: - host: gitlab-host # Identifies one of the hosts set up in the integrations - branch: main # Optional. Uses `master` as default - entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml` -``` diff --git a/.changeset/two-owls-cry.md b/.changeset/two-owls-cry.md deleted file mode 100644 index ca371781a1..0000000000 --- a/.changeset/two-owls-cry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-search-backend-module-elasticsearch': patch ---- - -Throws `MissingIndexError` when no index of type exist. diff --git a/.changeset/two-planets-provide.md b/.changeset/two-planets-provide.md new file mode 100644 index 0000000000..920eebc01d --- /dev/null +++ b/.changeset/two-planets-provide.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-scaffolder': minor +--- + +Implementing review step for the scaffolder under `create/next` diff --git a/.changeset/unlucky-stingrays-juggle.md b/.changeset/unlucky-stingrays-juggle.md deleted file mode 100644 index f2e83f7163..0000000000 --- a/.changeset/unlucky-stingrays-juggle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-catalog-import': patch ---- - -Support use without `integrations` or only integrations without frontend visible properties (e.g., `bitbucketCloud`) being configured by checking `integrations.github` directly without attempting to load `integrations`. diff --git a/.changeset/warm-monkeys-study.md b/.changeset/warm-monkeys-study.md deleted file mode 100644 index ae9ab4565c..0000000000 --- a/.changeset/warm-monkeys-study.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/core-plugin-api': patch ---- - -Enabled the `@backstage/core-plugin-api/alpha` entry point. diff --git a/.changeset/warm-paws-sneeze.md b/.changeset/warm-paws-sneeze.md deleted file mode 100644 index e620074f43..0000000000 --- a/.changeset/warm-paws-sneeze.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/errors': patch ---- - -Inline the type of `ConsumedResponse.headers` and tweaked it to be the intersection of the built-in type and `node-fetch` type. diff --git a/.changeset/weak-bananas-deliver.md b/.changeset/weak-bananas-deliver.md deleted file mode 100644 index f46c7b7bfe..0000000000 --- a/.changeset/weak-bananas-deliver.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -'@backstage/plugin-pagerduty': minor ---- - -Introduces a new annotation `pagerduty.com/service-id` that can be used instead of the `pagerduty.com/integration-key` annotation. -_Note: If both annotations are specified on a given Entity, then the `pagerduty.com/integration-key` annotation will be prefered_ - -**BREAKING** The `PagerDutyClient.fromConfig` static method now expects a `FetchApi` compatible object and has been refactored to -accept 2 arguments: config and ClientApiDependencies -The `PagerDutyClient` now relies on a `fetchApi` being available to execute `fetch` requests. - -**BREAKING** A new query method `getServiceByEntity` that is used to query for Services by either the `integrationKey` or `serviceId` -annotation values if they are defined. The `integrationKey` value is preferred currently over `serviceId`. As such, the previous -`getServiceByIntegrationKey` method has been removed. - -**BREAKING** The return values for each Client query method has been changed to return an object instead of raw values. -For example, the `getIncidentsByServiceId` query method now returns an object in the shape of `{ incidents: Incident[] }` -instead of just `Incident[]`. -This same pattern goes for `getChangeEventsByServiceId` and `getOnCallByPolicyId` functions. - -**BREAKING** All public exported types that relate to entities within PagerDuty have been prefixed with `PagerDuty` (e.g. `ServicesResponse` is now `PagerDutyServicesResponse` and `User` is now `PagerDutyUser`) - -In addition, various enhancements/bug fixes were introduced: - -- The `PagerDutyCard` component now wraps error and loading messages with an `InfoCard` to contain errors/messages. This enforces a consistent experience on the EntityPage -- If no service can be found for the provided integration key, a new Error Message Empty State component will be shown instead of an error alert -- Introduces the `fetchApi` to replace standard `window.fetch` - - ensures that Identity Authorization is respected and provided in API requests diff --git a/.changeset/weak-jeans-cry.md b/.changeset/weak-jeans-cry.md deleted file mode 100644 index 79f419e3db..0000000000 --- a/.changeset/weak-jeans-cry.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Add `allowArbitraryValues` to `ui:options` in `OwnedEntityPicker`, similar to `allowArbitraryValues` in `EntityPicker` diff --git a/.changeset/weak-llamas-repeat.md b/.changeset/weak-llamas-repeat.md deleted file mode 100644 index a86ce3a964..0000000000 --- a/.changeset/weak-llamas-repeat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-techdocs-backend': minor ---- - -Added local publishing target directory `config`: `techdocs.publisher.local.publishDirectory` diff --git a/.changeset/weak-yaks-learn.md b/.changeset/weak-yaks-learn.md new file mode 100644 index 0000000000..7a94e10d68 --- /dev/null +++ b/.changeset/weak-yaks-learn.md @@ -0,0 +1,49 @@ +--- +'@backstage/plugin-azure-devops': minor +'@backstage/plugin-azure-devops-common': minor +--- + +Added README card `EntityAzureReadmeCard` for Azure Devops. + +To get the README component working you'll need to do the following two steps: + +1. First we need to add the @backstage/plugin-azure-devops package to your frontend app: + + ```bash + # From your Backstage root directory + yarn add --cwd packages/app @backstage/plugin-azure-devops + ``` + +2. Second we need to add the `EntityAzureReadmeCard` extension to the entity page in your app: + + ```tsx + // In packages/app/src/components/catalog/EntityPage.tsx + import { + EntityAzureReadmeCard, + isAzureDevOpsAvailable, + } from '@backstage/plugin-azure-devops'; + + // As it is a card, you can customize it the way you prefer + // For example in the Service section + + const overviewContent = ( + + + + + ... + + + + + + + + ); + ``` + +**Notes:** + +- You'll need to add the `EntitySwitch.Case` above from step 2 to all the entity sections you want to see Readme in. For example if you wanted to see Readme when looking at Website entities then you would need to add this to the `websiteEntityPage` section. +- The `if` prop is optional on the `EntitySwitch.Case`, you can remove it if you always want to see the tab even if the entity being viewed does not have the needed annotation +- The `maxHeight` property on the `EntityAzureReadmeCard` will set the maximum screen size you would like to see, if not set it will default to 100% diff --git a/.changeset/wet-cameras-juggle.md b/.changeset/wet-cameras-juggle.md deleted file mode 100644 index 62cc206356..0000000000 --- a/.changeset/wet-cameras-juggle.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@backstage/plugin-azure-devops-backend': patch -'@backstage/plugin-azure-devops-common': patch ---- - -Adding getProjects endpoint to list out all projects associated with the Azure DevOps organization. - -It can be accessed by using this endpoint `{backendUrl}/api/azure-devops/projects` diff --git a/.changeset/wet-dolphins-act.md b/.changeset/wet-dolphins-act.md deleted file mode 100644 index b975f464cb..0000000000 --- a/.changeset/wet-dolphins-act.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-github-actions': patch ---- - -Minor cleanup of the API surface. diff --git a/.changeset/wicked-dragons-brush.md b/.changeset/wicked-dragons-brush.md deleted file mode 100644 index 737451f1fd..0000000000 --- a/.changeset/wicked-dragons-brush.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@backstage/plugin-techdocs': minor ---- - -Use the same initial filter `owned` for the `TechDocsIndexPage` as for the `CatalogPage`. - -If you prefer to keep the previous behavior, you can change the default for the initial filter -to `all` (or `starred` if you rather prefer that). - -``` - -``` - -In general, with this change you will be able to set props at `TechDocsIndexPage`. diff --git a/.changeset/wicked-icons-grin.md b/.changeset/wicked-icons-grin.md deleted file mode 100644 index 8d26a9255e..0000000000 --- a/.changeset/wicked-icons-grin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch ---- - -Swap usage of `MaterialTable` with `Table` from `core-components` diff --git a/.changeset/wicked-ladybugs-argue.md b/.changeset/wicked-ladybugs-argue.md deleted file mode 100644 index 9a36cf17cb..0000000000 --- a/.changeset/wicked-ladybugs-argue.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -'@backstage/plugin-catalog': patch -'@backstage/plugin-catalog-react': patch ---- - -Added new `EntityProcessingStatusPicker` that will filter for entities with orphans and/or errors. - -If you are using the default Catalog page this picker will be added automatically. For those who have customized their Catalog page you'll need to add this manually by doing something like this: - -```diff -... -import { - CatalogFilterLayout, - EntityTypePicker, - UserListPicker, - EntityTagPicker -+ EntityProcessingStatusPicker, -} from '@backstage/plugin-catalog-react'; -... -export const CustomCatalogPage = ({ - columns, - actions, - initiallySelectedFilter = 'owned', -}: CatalogPageProps) => { - return ( - ... - - - - - - ... -}; -``` diff --git a/.changeset/wild-sheep-roll.md b/.changeset/wild-sheep-roll.md new file mode 100644 index 0000000000..1551100b2a --- /dev/null +++ b/.changeset/wild-sheep-roll.md @@ -0,0 +1,8 @@ +--- +'@backstage/core-components': patch +'@backstage/plugin-adr': patch +'@backstage/plugin-apache-airflow': patch +'@backstage/plugin-api-docs': patch +--- + +Minor cleanup of the public API surface to reduce the number of warnings diff --git a/.changeset/witty-cats-wink.md b/.changeset/witty-cats-wink.md new file mode 100644 index 0000000000..82f6d3098f --- /dev/null +++ b/.changeset/witty-cats-wink.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend-module-msgraph': patch +--- + +Fix typo diff --git a/.changeset/witty-ladybugs-laugh.md b/.changeset/witty-ladybugs-laugh.md deleted file mode 100644 index d47bbb3250..0000000000 --- a/.changeset/witty-ladybugs-laugh.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-scaffolder': patch -'@backstage/plugin-scaffolder-backend': patch ---- - -Allow to create Gerrit project using default owner diff --git a/.changeset/young-seas-report.md b/.changeset/young-seas-report.md deleted file mode 100644 index 388dada7e7..0000000000 --- a/.changeset/young-seas-report.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@backstage/plugin-bazaar': patch -'@backstage/plugin-bazaar-backend': patch ---- - -Fixed api warnings diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 113ca7757d..f00771d29d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -22,7 +22,11 @@ yarn.lock @backstage/reviewers @backst /plugins/azure-devops @backstage/reviewers @marleypowell @awanlin /plugins/azure-devops-backend @backstage/reviewers @marleypowell @awanlin /plugins/azure-devops-common @backstage/reviewers @marleypowell @awanlin +/plugins/bitbucket-cloud-common @backstage/reviewers @pjungermann /plugins/bitrise @backstage/reviewers @backstage/sda-se-reviewers +/plugins/catalog-backend-module-aws @backstage/reviewers @pjungermann +/plugins/catalog-backend-module-bitbucket-cloud @backstage/reviewers @pjungermann +/plugins/catalog-backend-module-msgraph @backstage/reviewers @pjungermann /plugins/catalog-graph @backstage/reviewers @backstage/sda-se-reviewers /plugins/circleci @backstage/reviewers @adamdmharvey /plugins/cloudbuild @backstage/reviewers @trivago/ebarrios diff --git a/.github/vale/Vocab/Backstage/accept.txt b/.github/vale/Vocab/Backstage/accept.txt index 8428dc2d0e..ae94912f38 100644 --- a/.github/vale/Vocab/Backstage/accept.txt +++ b/.github/vale/Vocab/Backstage/accept.txt @@ -281,8 +281,11 @@ serializable Serverless shoutout siloed +SIG +SIGs Sinon Snyk +Sonarqube sourcemaps sparklines Splunk @@ -310,6 +313,7 @@ Talkdesk tasklist techdocs Telenor +telus templated templater Templater @@ -362,3 +366,4 @@ Zhou zoomable zsh Alef +Cloudflare diff --git a/.github/workflows/deploy_docker-image.yml b/.github/workflows/deploy_docker-image.yml index 93d59b64bd..f61c51ab32 100644 --- a/.github/workflows/deploy_docker-image.yml +++ b/.github/workflows/deploy_docker-image.yml @@ -1,4 +1,4 @@ -name: Build and push Docker Hub image +name: Build and push Docker image on: repository_dispatch: types: [release-published] @@ -87,3 +87,5 @@ jobs: tags: | ghcr.io/${{ github.repository_owner }}/backstage:latest ghcr.io/${{ github.repository_owner }}/backstage:${{ github.event.client_payload.version }} + labels: | + org.opencontainers.image.description=Docker image generated from the latest Backstage release; this contains what you would get out of the box by running npx @backstage/create-app and building a Docker image from the generated source. This is meant to ease the process of evaluating Backstage for the first time, but also has the severe limitation that there is no way to install additional plugins relevant to your infrastructure. diff --git a/.github/workflows/deploy_microsite.yml b/.github/workflows/deploy_microsite.yml index ffada71523..7a046f3c56 100644 --- a/.github/workflows/deploy_microsite.yml +++ b/.github/workflows/deploy_microsite.yml @@ -55,7 +55,7 @@ jobs: run: ls microsite/build/backstage && ls microsite/build/backstage/storybook - name: Deploy both microsite and storybook to gh-pages - uses: JamesIves/github-pages-deploy-action@v4.3.4 + uses: JamesIves/github-pages-deploy-action@v4.4.0 with: branch: gh-pages folder: microsite/build/backstage diff --git a/ADOPTERS.md b/ADOPTERS.md index 7b6b56874e..902952a90e 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -28,7 +28,6 @@ _You can do this by using the [Adopter form](https://form.typeform.com/to/zcOaKi | [Lunar](https://lunar.app) | [Jacob Valdemar](https://github.com/JacobValdemar) | Internal developer portal for service overview and insights, API documentation, technical guides, onboarding guides and RFC's. | | [Trendyol](https://trendyol.com) | [Gamze Senturk](https://github.com/gmzsenturk), [Mert Can Bilgic](https://github.com/mertcb) | The Developer Portal has been called `Pandora`. Provides an overview of Trendyol tech ecosystem. TechDocs, Catalog, Custom Plugins and Theme. | | [Peloton](https://www.onepeloton.com/) | [Matt Waldron](https://github.com/daftgopher) | Creating our first developer portal and tech-docs. Exploring Service Catalog, Tech Insights and Cost Insights as well. | -| [TELUS](https://telus.com) | [Seb Barre](https://github.com/sbarre) | The Go-to place to find answers about development and delivery at TELUS. | | [Brex](https://www.brex.com/) | [Vamsi Chitters](https://github.com/vamsikc) | A centralized UI to understand how a service fits in the whole Brex architecture and manage a team’s engineering dependencies. | | [Oriflame](https://www.oriflame.com/) | [Oriflame](https://github.com/oriflame) | Internal developer portal for services, single page apps and packages overview, API documentation, technical guides, tech-radar and more. | | [Booz Allen Hamilton](https://www.boozallen.com/) | [Jason Miller](https://github.com/JasonMiller-BAH) | Developer portal for a full-stack software development ecosystem that accelerates consistent and repeatable Modern Software Development practices for internal innovation and investments. | @@ -168,7 +167,7 @@ _You can do this by using the [Adopter form](https://form.typeform.com/to/zcOaKi | [Forto](https://forto.com) | [Rodolfo Matos](mailto:rodolfo.matos@forto.com) | Still in a experimental phase/assessing the organisational fit. We will be using it mostly a developer portal -- pretty standard use case. | | [BetterUp](https://betterup.com) | [Jordan Hochenbaum](mailto:jordan.hochenbaum@betterup.co) | We're starting to use Backstage as the central hub for service discovery, documentation, and develop experience. | | [warung pintar](https://warungpintar.co.id/) | [Muhammad Rafly Andrianza](mailto:rafly.andrianza@warungpintar.co) | Initial Work Developer Portal with TechRadar, Service Catalogue, TechDocs, anything about platform & infrastructure resources. | -| [RaiaDrogasil](https://rd.com.br/) | [Michael Lima](mailto:midsilva@rd.com.br) | We are building our developer portal. Software catalog, Tech Radar and Scaffolding are among the initial features. | +| [RaiaDrogasil](https://rd.com.br/) | [Michael Lima](mailto:midsilva@rd.com.br) | We are building our developer portal. Software catalog, Tech Radar and Scaffolding are among the initial features. | | [AEB](https://www.aeb.com/) | [David Fankhänel](mailto:dfl@aeb.com) | Central developer platform for creating new apps via templates, getting an overview via software catalog, etc | | [SALTO Systems](https://saltosystems.com) | [Ian Cowley](mailto:i.cowley@saltosystems.com) | Currently using Backstage as an internal documentation portal. | | [Lummo](https://lummo.com) | [Anjul Sahu](mailto:anjul@lummo.com) | We are building the internal developer portal using Backstage and bringing up all integrations and service information at one place. | @@ -196,6 +195,16 @@ _You can do this by using the [Adopter form](https://form.typeform.com/to/zcOaKi | [Adaptavist](https://adaptavist.com) | [Lilly Holden](mailto:lholden@adaptavist.com) | Developer portal, service catalog, documentation and self-service platform | | [Shipshape](https://shipshape.io) | [Chuck Carpenter](mailto:chuck@shipshape.io) | We are a consultancy helping teams implement and customize Backstage. | | [Backbase](https://backbase.com) | [Nicolas Torres](mailto:ntorres.dev@gmail.com) | To catalog components and teams | -| [https://www.clear.sale](https://www.clear.sale) | [Paulo Baima](mailto:paulo.filho@clear.sale) | Central Hub for all the company modules, enabling the track of ownership of components and resources and how they relate to each other. | -| [www.leroymerlin.com.br](https://www.leroymerlin.com.br) | [Rodrigo Franzoni](mailto:rfranzoni@leroymerlin.com.br) | Our engineers use the Backstage to solve problems around ownership and visibility of our applications, access service catalog, documentation, observability and infrastructure. | +| [clearSale](https://www.clear.sale) | [Paulo Baima](mailto:paulo.filho@clear.sale) | Central Hub for all the company modules, enabling the track of ownership of components and resources and how they relate to each other. | +| [LeroyMerlin](https://www.leroymerlin.com.br) | [Rodrigo Franzoni](mailto:rfranzoni@leroymerlin.com.br) | Our engineers use the Backstage to solve problems around ownership and visibility of our applications, access service catalog, documentation, observability and infrastructure. | | [Intility](https://intility.no/en/) | [@daniwk](https://github.com/daniwk) | We are creating a developer portal powered by Backstage, with software catalog, documentation, templates and integrations to our infrastructure and internal tools. | +| [ImmobiliareLabs](https://labs.immobiliare.it/) | [@JellyBellyDev](https://github.com/JellyBellyDev) | Centralized portal with our internal services, infrastructures, relationships between systems, technical documentation, templates, monitoring and custom integrations with our own DX tools. | +| [Skillz](https://skillz.com/) | [Peiman Jafari](https://github.com/peimanja) | Internal developers portal for technical documentations, components ownership and relationship, software templates and integrations with internal tools | +| [Telus](https://www.telus.com/en/) | [Leo Li](mailto:leo.li@telus.com), [Laurent Robichaud](mailto:laurent.robichaud@telus.com), [Seb Barre](https://github.com/sbarre) | Simplifying the developer experience through centralized team member portals. Our current focus includes the adoption of Tech Docs, Software Catalog, Software Templates, the plethora of plugins, and contributing features back to Backstage. 🤖 | +| [Fidelity Investments](https://fidelity.com) | [Ankita Upadhyay](mailto:ankita.upadhyay@fmr.com) | Getting started with the adoption for Monorepo projects | +| [Verisk](https://verisk.com) | [Callen Barton](mailto:cbarton@verisk.com) | Developer portal to quickly create and deploy microservices. | +| [iodigital](https://iodigital.com) | [Jan-Willem Mulder](mailto:jan-willem.mulder@iodigital.com) | Internal developer portal for discovery of applications, projects and teams. Using several plugins like the Software Catalog and Tech Insights for promoting best practices and supporting our SDLC toolchain | +| [Fanatics](https://www.fanaticsinc.com/) | [Rory Scott](mailto:rscott@fanatics.com) | Internal Portal consolidating documentation, making it easier to manage applications, internal developer community platform, and self-service cloud infrastructure + pipelines. | +| [Appfolio](https://appfolio.com) | [Andy Vaughn](mailto:andy.vaughn@appfolio.com) | Internal software catalog, tech radar, documentation portal to disambiguate software and domain ownership, foster exploration of available developer platform services and tools, improve communication, democratize documentation and knowledge sharing, and coordinate the software lifecycle; all in service of a best-in-class developer experience. | +| [isaac](https://isaac.com.br/) | [Leonardo Borges](mailto:leonardo.borges@isaac.com.br), [Ordilei Souza](mailto:ordilei.souza@isaac.com.br) | We're using Backstage as our Internal Developer Portal and main microservices catalog for mapping ownership, health and metrics for each one. | +| [Paraná Banco](https://site.paranabanco.com.br/) | [Joao Antunes](mailto:joaopma@pbtech.net.br) | Internal software catalog, documentation and ownership, improve communication, democratize documentation and knowledge sharing, and coordinate the software lifecycle; all in service of a best-in-class developer experience. | \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1afbf072fc..f658799a85 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,10 +36,16 @@ You can also use this process if you have an idea for a good plugin but you hope Since there is such a large landscape of possible development, build, and deployment environments, we welcome community contributions in these areas in the [`/contrib`](https://github.com/backstage/backstage/tree/master/contrib) folder of the project. This is an excellent place to put things that help out the community at large, but which may not fit within the scope of the core product to support natively. Here, you will find Helm charts, alternative Docker images, and much more. -### Write Documentation +### Write Documentation or improve the website The current documentation is very limited. Help us make the `/docs` folder come alive. +Docs are published to [backstage.io/docs](https://backstage.io/docs). If you +contribute to the documentation, you might want to preview your changes before +submitting them. You'll find the website sources under [/microsite](/microsite) +with instructions for building and locally serving the website in the +[README](/microsite#readme). + ### Contribute to Storybook We think the best way to ensure different plugins provide a consistent experience is through a solid set of reusable UI/UX components. Backstage uses [Storybook](http://backstage.io/storybook). diff --git a/README.md b/README.md index a6e740a427..5dba1fdf52 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,5 @@ ![headline](docs/assets/headline.png) -> 🏖 From July 7th due to Summer Vacations for some of the maintainers, expect the project to move a little slower than normal, and support to be limited. Normal service will resume on August 8th 🏝 - # [Backstage](https://backstage.io) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) diff --git a/SECURITY.md b/SECURITY.md index 49e26349b0..5866fff2b4 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,9 +2,7 @@ ## Supported Versions -| Version | Supported | -| ------- | ------------------ | -| 0.x | :white_check_mark: | +See our [Release & Versioning Policy](https://backstage.io/docs/overview/versioning-policy#release-versioning-policy). ## Reporting a Vulnerability diff --git a/app-config.yaml b/app-config.yaml index 9a3206026e..32b53da236 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -39,7 +39,7 @@ backend: store: memory cors: origin: http://localhost:3000 - methods: [GET, POST, PUT, DELETE] + methods: [GET, HEAD, PATCH, POST, PUT, DELETE] credentials: true csp: connect-src: ["'self'", 'http:', 'https:'] @@ -161,6 +161,7 @@ kafka: clientId: backstage clusters: - name: cluster + dashboardUrl: https://akhq.io/ brokers: - localhost:9092 diff --git a/contrib/docker/cookiecutter-with-jinja2-extensions/Dockerfile b/contrib/docker/cookiecutter-with-jinja2-extensions/Dockerfile deleted file mode 100644 index e41d324730..0000000000 --- a/contrib/docker/cookiecutter-with-jinja2-extensions/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM alpine:3.16 - -RUN apk add --update \ - git \ - python \ - python-dev \ - py-pip \ - g++ && \ - pip install cookiecutter jinja2_custom_filters_extension && \ - apk del g++ py-pip python-dev && \ - rm -rf /var/cache/apk/* diff --git a/contrib/docker/cookiecutter-with-jinja2-extensions/README.md b/contrib/docker/cookiecutter-with-jinja2-extensions/README.md index 470694513a..0b754fa4ce 100644 --- a/contrib/docker/cookiecutter-with-jinja2-extensions/README.md +++ b/contrib/docker/cookiecutter-with-jinja2-extensions/README.md @@ -51,7 +51,7 @@ steps: imageName: 'foo/custom-built-cookiecutter-image-with-extensions' ``` -See for example, the [`Dockerfile`](./Dockerfile) in this directory. +For example, you can `pip install jinja2_custom_filters_extension` as part of your cookiecutter Dockerfile. ### Instructing Cookiecutter to use the extension diff --git a/contrib/docker/kubernetes-example-backend/Dockerfile b/contrib/docker/kubernetes-example-backend/Dockerfile deleted file mode 100644 index 4f4105838d..0000000000 --- a/contrib/docker/kubernetes-example-backend/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -FROM node:14-buster - -WORKDIR /usr/src/app - -# (workaround) Install cookiecutter and mkdocs to avoid the need to run docker in docker -RUN cd /tmp && curl -O https://www.python.org/ftp/python/3.8.2/Python-3.8.2.tar.xz && \ - tar -xvf Python-3.8.2.tar.xz && \ - cd Python-3.8.2 && \ - ./configure --enable-optimizations && \ - make -j 4 && \ - make altinstall - -RUN apt update -RUN apt install -y mkdocs - -RUN pip3.8 install mkdocs-techdocs-core - -RUN pip3.8 install cookiecutter && \ - apt remove -y build-essential zlib1g-dev libncurses5-dev libgdbm-dev libnss3-dev libssl-dev libsqlite3-dev libreadline-dev libffi-dev libbz2-dev g++ python-pip python-dev && \ - rm -rf /var/cache/apt/* /tmp/Python-3.8.2 - -# Copy repo skeleton first, to avoid unnecessary docker cache invalidation. -# The skeleton contains the package.json of each package in the monorepo, -# and along with yarn.lock and the root package.json, that's enough to run yarn install. -ADD yarn.lock package.json skeleton.tar ./ - -RUN yarn install --frozen-lockfile --production - -# This will copy the contents of the dist-workspace when running the build-image command. -# Do not use this Dockerfile outside of that command, as it will copy in the source code instead. -COPY . . - -CMD ["node", "packages/backend", "--config", "app-config.yaml", "--config", "app-config.development.yaml"] diff --git a/contrib/docker/kubernetes-example-backend/README.md b/contrib/docker/kubernetes-example-backend/README.md deleted file mode 100644 index d0f9d57022..0000000000 --- a/contrib/docker/kubernetes-example-backend/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Example backend Dockerfile - -This Dockerfile will build the example backend with certain additional binaries needed to workaround -the docker requirement in the scaffolder and techdocs. - -# Usage - -```bash -yarn docker-build -f --tag -``` - -> The absolute path is necessary as this directory is not copied to the build workspace when building -> the docker image. diff --git a/contrib/kubernetes/basic_kubernetes_example_with_helm/README.md b/contrib/kubernetes/basic_kubernetes_example_with_helm/README.md index 2dc875f671..c18329f59e 100644 --- a/contrib/kubernetes/basic_kubernetes_example_with_helm/README.md +++ b/contrib/kubernetes/basic_kubernetes_example_with_helm/README.md @@ -1 +1,3 @@ # Basic Kubernetes example with Helm + +Note that these examples aim to show a minimal setup and do not include best practices for secure Kubernetes deployments. See the [Kubernetes documentation](https://kubernetes.io/docs/concepts/security/) for more information, or resources provided by your own organization. diff --git a/cypress/yarn.lock b/cypress/yarn.lock index 991d2d8562..2f1e0f0775 100644 --- a/cypress/yarn.lock +++ b/cypress/yarn.lock @@ -40,14 +40,14 @@ lodash.once "^4.1.1" "@types/node@*": - version "18.0.0" - resolved "https://registry.npmjs.org/@types/node/-/node-18.0.0.tgz#67c7b724e1bcdd7a8821ce0d5ee184d3b4dd525a" - integrity sha512-cHlGmko4gWLVI27cGJntjs/Sj8th9aYwplmZFwmmgYQQvL5NUsgVJG7OddLvNfLqYS31KFN0s3qlaD9qCaxACA== + version "18.7.6" + resolved "https://registry.npmjs.org/@types/node/-/node-18.7.6.tgz#31743bc5772b6ac223845e18c3fc26f042713c83" + integrity sha512-EdxgKRXgYsNITy5mjjXjVE/CS8YENSdhiagGrLqjG0pvA2owgJ6i4l7wy/PFZGC0B1/H20lWKN7ONVDNYDZm7A== "@types/node@^14.14.31": - version "14.18.21" - resolved "https://registry.npmjs.org/@types/node/-/node-14.18.21.tgz#0155ee46f6be28b2ff0342ca1a9b9fd4468bef41" - integrity sha512-x5W9s+8P4XteaxT/jKF0PSb7XEvo5VmqEWgsMlyeY4ZlLK8I6aH6g5TPPyDlLAep+GYf4kefb7HFyc7PAO3m+Q== + version "14.18.24" + resolved "https://registry.npmjs.org/@types/node/-/node-14.18.24.tgz#406b220dc748947e1959d8a38a75979e87166704" + integrity sha512-aJdn8XErcSrfr7k8ZDDfU6/2OgjZcB2Fu9d+ESK8D7Oa5mtsv8Fa8GpcwTA0v60kuZBaalKPzuzun4Ov1YWO/w== "@types/sinonjs__fake-timers@8.1.1": version "8.1.1" @@ -304,9 +304,9 @@ cross-spawn@^7.0.0: which "^2.0.1" cypress@^10.0.0: - version "10.3.0" - resolved "https://registry.npmjs.org/cypress/-/cypress-10.3.0.tgz#fae8d32f0822fcfb938e79c7c31ef344794336ae" - integrity sha512-txkQWKzvBVnWdCuKs5Xc08gjpO89W2Dom2wpZgT9zWZT5jXxqPIxqP/NC1YArtkpmp3fN5HW8aDjYBizHLUFvg== + version "10.6.0" + resolved "https://registry.npmjs.org/cypress/-/cypress-10.6.0.tgz#13f46867febf2c3715874ed5dce9c2e946b175fe" + integrity sha512-6sOpHjostp8gcLO34p6r/Ci342lBs8S5z9/eb3ZCQ22w2cIhMWGUoGKkosabPBfKcvRS9BE4UxybBtlIs8gTQA== dependencies: "@cypress/request" "^2.88.10" "@cypress/xvfb" "^1.2.4" @@ -359,9 +359,9 @@ dashdash@^1.12.0: assert-plus "^1.0.0" dayjs@^1.10.4: - version "1.11.3" - resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz#4754eb694a624057b9ad2224b67b15d552589258" - integrity sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A== + version "1.11.5" + resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.5.tgz#00e8cc627f231f9499c19b38af49f56dc0ac5e93" + integrity sha512-CAdX5Q3YW3Gclyo5Vpqkgpj8fSdLQcRuzfX6mC6Phy0nfJ0eGYOeS7m4mt2plDWLAtA4TqTakvbboHvUxfe4iA== debug@^3.1.0: version "3.2.7" @@ -415,9 +415,9 @@ escape-string-regexp@^1.0.5: integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== eventemitter2@^6.4.3: - version "6.4.5" - resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz#97380f758ae24ac15df8353e0cc27f8b95644655" - integrity sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw== + version "6.4.7" + resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d" + integrity sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg== execa@4.1.0: version "4.1.0" @@ -853,9 +853,9 @@ proxy-from-env@1.0.0: integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== psl@^1.1.28: - version "1.8.0" - resolved "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + version "1.9.0" + resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== pump@^3.0.0: version "3.0.0" @@ -903,9 +903,9 @@ rimraf@^3.0.0: glob "^7.1.3" rxjs@^7.5.1: - version "7.5.5" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" - integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw== + version "7.5.6" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" + integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw== dependencies: tslib "^2.1.0" diff --git a/docs/assets/getting-started/add-icons-links-example.png b/docs/assets/getting-started/add-icons-links-example.png new file mode 100644 index 0000000000..dfff84b79c Binary files /dev/null and b/docs/assets/getting-started/add-icons-links-example.png differ diff --git a/docs/auth/cloudflare/access.md b/docs/auth/cloudflare/access.md new file mode 100644 index 0000000000..c7db308438 --- /dev/null +++ b/docs/auth/cloudflare/access.md @@ -0,0 +1,100 @@ +--- +id: cfaccess +title: Cloudflare Access Provider +sidebar_label: cfaccess +# prettier-ignore +description: Adding Cloudflare Access as an authentication provider in Backstage +--- + +Similar to GCP IAP Proxy Provider or AWS ALB provider, developers can offload authentication +support to Cloudflare Access. + +This tutorial shows how to use authentication on Cloudflare Access sitting in +front of Backstage. + +It is assumed a Cloudflare tunnel is already serving traffic in front of a +Backstage instance configured to serve the frontend app from the backend and is +already gated using Cloudflare Access. + +## Configuration + +Let's start by adding the following `auth` configuration in your +`app-config.yaml` or `app-config.production.yaml` or similar: + +```yaml +auth: + providers: + cfaccess: + teamName: +``` + +You can find the team name in the Cloudflare Zero Trust dashboard. + +This config section must be in place for the provider to load at all. Now let's +add the provider itself. + +## Backend Changes + +Add a `providerFactories` entry to the router in +`packages/backend/plugin/auth.ts`. + +```ts +import { providers } from '@backstage/plugin-auth-backend'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return await createRouter({ + logger: env.logger, + config: env.config, + database: env.database, + discovery: env.discovery, + providerFactories: { + 'cfaccess': providers.cfAccess.create({ + // Replace the auth handler if you want to customize the returned user + // profile info (can be left out; the default implementation is shown + // below which only returns the email). You may want to amend this code + // with something that loads additional user profile data out. + async authHandler({ accessToken }) { + return { profile: { email: accessToken.email } }; + }, + signIn: { + // You need to supply an identity resolver, that takes the profile + // and the access token and produces the Backstage token with the + // relevant user info. + async resolver({ profile, result }, ctx) { + // Somehow compute the Backstage token claims. Just some dummy code + // shown here, but you may want to query your LDAP server, or + // https://.cloudflareaccess.com/cdn-cgi/access/get-identity + // https://developers.cloudflare.com/cloudflare-one/identity/users/validating-json/#groups-within-a-jwt + const id = profile.email.split('@')[0]; + const sub = stringifyEntityRef({ kind: 'User', name: id }); + const ent = [sub, stringifyEntityRef({ kind: 'Group', name: 'team-name' }); + return ctx.issueToken({ claims: { sub, ent } }); + }, + }, + }), + }, + }); +} +``` + +Now the backend is ready to serve auth requests on the +`/api/auth/cfaccess/refresh` endpoint. All that's left is to update the +frontend sign-in mechanism to poll that endpoint through Cloudflare Access, on +the user's behalf. + +## Adding the provider to the Backstage frontend + +It is recommended to use the `ProxiedSignInPage` for this provider, which is +installed in `packages/app/src/App.tsx` like this: + +```diff ++import { ProxiedSignInPage } from '@backstage/core-components'; + + const app = createApp({ + components: { ++ SignInPage: props => , +``` + +See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page to also work smoothly for local development. diff --git a/docs/auth/identity-resolver.md b/docs/auth/identity-resolver.md index 06ada040e4..681b2f9927 100644 --- a/docs/auth/identity-resolver.md +++ b/docs/auth/identity-resolver.md @@ -207,7 +207,7 @@ of lower-level calls: ```ts // File: packages/backend/src/plugins/auth.ts -import { getDefaultOwnershipRefs } from '@backstage/plugin-auth-backend'; +import { getDefaultOwnershipEntityRefs } from '@backstage/plugin-auth-backend'; export default async function createPlugin( // ... @@ -236,7 +236,7 @@ export default async function createPlugin( // an entity you will need to replace this step as well. // // You might also replace it if you for example want to filter out certain groups. - const ownershipRefs = getDefaultOwnershipRefs(entity); + const ownershipRefs = getDefaultOwnershipEntityRefs(entity); // The last step is to issue the token, where we might provide more options in the future. return ctx.issueToken({ @@ -273,46 +273,57 @@ that the user belongs to using the user access token in the provided result obje ```ts // File: packages/backend/src/plugins/auth.ts -import { DEFAULT_NAMESPACE, stringifyEntityRef, } from '@backstage/catalog-model'; +import { createRouter, providers } from '@backstage/plugin-auth-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; +import { + stringifyEntityRef, + DEFAULT_NAMESPACE, +} from '@backstage/catalog-model'; export default async function createPlugin( - // ... + env: PluginEnvironment, +): Promise { return await createRouter({ - // ... + ...env, providerFactories: { - // ... - google: async ({ profile }, ctx) => { - if (!profile.email) { - throw new Error( - 'Login failed, user profile does not contain an email', - ); - } - // Split the email into the local part and the domain. - const [localPart, domain] = profile.email.split('@'); + google: providers.google.create({ + signIn: { + resolver: async ({ profile }, ctx) => { + if (!profile.email) { + throw new Error( + 'Login failed, user profile does not contain an email', + ); + } + // Split the email into the local part and the domain. + const [localPart, domain] = profile.email.split('@'); - // Next we verify the email domain. It is recommended to include this - // kind of check if you don't look up the user in an external service. - if (domain !== 'acme.org') { - throw new Error('Login failed, user email domain check failed'); - } + // Next we verify the email domain. It is recommended to include this + // kind of check if you don't look up the user in an external service. + if (domain !== 'acme.org') { + throw new Error( + `Login failed, this email ${profile.email} does not belong to the expected domain`, + ); + } - // By using `stringifyEntityRef` we ensure that the reference is formatted correctly - const userEntityRef = stringifyEntityRef({ - kind: 'User', - name: localPart, - namespace: DEFAULT_NAMESPACE, - }); - - return ctx.issueToken({ - claims: { - sub: userEntityRef, - ent: [userEntityRef], + // By using `stringifyEntityRef` we ensure that the reference is formatted correctly + const userEntity = stringifyEntityRef({ + kind: 'User', + name: localPart, + namespace: DEFAULT_NAMESPACE, + }); + return ctx.issueToken({ + claims: { + sub: userEntity, + ent: [userEntity], + }, + }); }, - }); - }, - } - }) -) + }, + }), + }, + }); +} ``` ## AuthHandler diff --git a/docs/auth/index.md b/docs/auth/index.md index e713e722ef..8d303c776d 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -18,6 +18,7 @@ Backstage comes with many common authentication providers in the core library: - [Auth0](auth0/provider.md) - [Azure](microsoft/provider.md) - [Bitbucket](bitbucket/provider.md) +- [Cloudflare Access](cloudflare/access.md) - [GitHub](github/provider.md) - [GitLab](gitlab/provider.md) - [Google](google/provider.md) @@ -131,7 +132,7 @@ allows allowing guest access: Some auth providers are so-called "proxy" providers, meaning they're meant to be used behind an authentication proxy. Examples of these are -[AWS ALB](https://github.com/backstage/backstage/blob/master/contrib/docs/tutorials/aws-alb-aad-oidc-auth.md), +[AWS ALB](https://github.com/backstage/backstage/blob/master/contrib/docs/tutorials/aws-alb-aad-oidc-auth.md), [Cloudflare Access](./cloudflare/access.md), [GCP IAP](./google/gcp-iap-auth.md), and [OAuth2 Proxy](./oauth2-proxy/provider.md). When using a proxy provider, you'll end up wanting to use a different sign-in page, as diff --git a/docs/deployment/docker.md b/docs/deployment/docker.md index 6471ada7f2..d46aff1b06 100644 --- a/docs/deployment/docker.md +++ b/docs/deployment/docker.md @@ -58,24 +58,30 @@ Once the host build is complete, we are ready to build our image. The following ```Dockerfile FROM node:16-bullseye-slim -WORKDIR /app - -# install sqlite3 dependencies, you can skip this if you don't use sqlite3 in the image +# Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, +# in which case you should also move better-sqlite3 to "devDependencies" in package.json. RUN apt-get update && \ apt-get install -y --no-install-recommends libsqlite3-dev python3 build-essential && \ rm -rf /var/lib/apt/lists/* && \ yarn config set python /usr/bin/python3 +# From here on we use the least-privileged `node` user to run the backend. +USER node +WORKDIR /app + +# This switches many Node.js dependencies to production mode. +ENV NODE_ENV production + # Copy repo skeleton first, to avoid unnecessary docker cache invalidation. # The skeleton contains the package.json of each package in the monorepo, # and along with yarn.lock and the root package.json, that's enough to run yarn install. -COPY yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./ +COPY --chown=node:node yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./ RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz RUN yarn install --frozen-lockfile --production --network-timeout 300000 && rm -rf "$(yarn cache dir)" # Then copy the rest of the backend bundle, along with any other files we might want. -COPY packages/backend/dist/bundle.tar.gz app-config.yaml ./ +COPY --chown=node:node packages/backend/dist/bundle.tar.gz app-config*.yaml ./ RUN tar xzf bundle.tar.gz && rm bundle.tar.gz CMD ["node", "packages/backend", "--config", "app-config.yaml"] @@ -176,26 +182,32 @@ RUN yarn --cwd packages/backend build # Stage 3 - Build the actual backend image and install production dependencies FROM node:16-bullseye-slim -WORKDIR /app - -# install sqlite3 dependencies, you can skip this if you don't use sqlite3 in the image +# Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, +# in which case you should also move better-sqlite3 to "devDependencies" in package.json. RUN apt-get update && \ apt-get install -y --no-install-recommends libsqlite3-dev python3 build-essential && \ rm -rf /var/lib/apt/lists/* && \ yarn config set python /usr/bin/python3 +# From here on we use the least-privileged `node` user to run the backend. +USER node +WORKDIR /app + +# This switches many Node.js dependencies to production mode. +ENV NODE_ENV production + # Copy the install dependencies from the build stage and context -COPY --from=build /app/yarn.lock /app/package.json /app/packages/backend/dist/skeleton.tar.gz ./ +COPY --from=build --chown=node:node /app/yarn.lock /app/package.json /app/packages/backend/dist/skeleton.tar.gz ./ RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz RUN yarn install --frozen-lockfile --production --network-timeout 600000 && rm -rf "$(yarn cache dir)" # Copy the built packages from the build stage -COPY --from=build /app/packages/backend/dist/bundle.tar.gz . +COPY --from=build --chown=node:node /app/packages/backend/dist/bundle.tar.gz . RUN tar xzf bundle.tar.gz && rm bundle.tar.gz # Copy any other files that we need at runtime -COPY app-config.yaml ./ +COPY --chown=node:node app-config.yaml ./ CMD ["node", "packages/backend", "--config", "app-config.yaml"] ``` diff --git a/docs/deployment/scaling.md b/docs/deployment/scaling.md new file mode 100644 index 0000000000..f3aa744cf7 --- /dev/null +++ b/docs/deployment/scaling.md @@ -0,0 +1,24 @@ +--- +id: scaling +title: Scaling Backstage Deployments +sidebar_label: Scaling +description: Scaling Backstage production deployments +--- + +There are several different methods for scaling Backstage deployments. The most +straight-forward one is to simply deploy multiple identical instances and distributing +incoming requests across them. The one requirement for this to work is that all instances +need to share the same external resources, such as the database, and optional caching or +search services. The Backstage backend plugins will coordinate through the database +to share state and coordinate work. + +Another method for scaling Backstage deployments is to break apart the backend +into multiple different services, each running a different set of plugins. This +is a more advanced approach and requires you to be able to route requests to +the appropriate backends based on the plugin ID. Both for ingress, but also +internal traffic between Backstage backends, which is done by creating a custom +implementation of the [PluginEndpointDiscover](../reference/backend-common.pluginendpointdiscovery.md) interface. + +Lastly, you can also replicate the Backstage deployments across multiple regions. +This is not a pattern that there is built-in support for and typically only makes +sense to do for individual backend plugins. diff --git a/docs/features/kubernetes/configuration.md b/docs/features/kubernetes/configuration.md index dce4e60a87..04a04304f9 100644 --- a/docs/features/kubernetes/configuration.md +++ b/docs/features/kubernetes/configuration.md @@ -31,6 +31,10 @@ kubernetes: dashboardUrl: http://127.0.0.1:64713 # url copied from running the command: minikube service kubernetes-dashboard -n kubernetes-dashboard dashboardApp: standard caData: ${K8S_CONFIG_CA_DATA} + customResources: + - group: 'argoproj.io' + apiVersion: 'v1alpha1' + plural: 'rollouts' - url: http://127.0.0.2:9999 name: aws-cluster-1 authProvider: 'aws' @@ -236,10 +240,12 @@ kubernetes: ##### `clusters.\*.caData` (optional) -PEM-encoded certificate authority certificates. +Base64-encoded certificate authority bundle in PEM format. The Kubernetes client +will verify that TLS certificate presented by the API server is signed by this +CA. -This values could be obtained via inspecting the Kubernetes config file (usually -at `~/.kube/config`) under `clusters.cluster.certificate-authority-data`. For +This value could be obtained via inspecting the kubeconfig file (usually +at `~/.kube/config`) under `clusters[*].cluster.certificate-authority-data`. For GKE, execute the following command to obtain the value ``` @@ -252,6 +258,11 @@ See also https://cloud.google.com/kubernetes-engine/docs/how-to/api-server-authentication#environments-without-gcloud for complete docs about GKE without `gcloud`. +##### `clusters.\*.customResources` (optional) + +Configures which [custom resources][3] to look for when returning an entity's +Kubernetes resources belonging to the cluster. Same specification as [`customResources`](#customresources-optional) + #### `gke` This cluster locator is designed to work with Kubernetes clusters running in @@ -325,9 +336,13 @@ it is also possible to implement a ### `customResources` (optional) -Configures which [custom resources][3] to look for when returning an entity's +Configures which [custom resources][3] to look for by default when returning an entity's Kubernetes resources. +**Notes:** + +- The optional `kubernetes.customResources` property is overrode by `customResources` at the [clusters level](#clusterscustomresources-optional). + Defaults to empty array. Example: ```yaml @@ -373,23 +388,43 @@ view the Kubernetes API docs for your Kubernetes version (e.g. ### Role Based Access Control -The current RBAC permissions required are read-only cluster wide, for the -following objects: +The current RBAC permissions required are read-only cluster wide, the below +Kubernetes manifest describes which objects are required and will ensure +the plugin functions correctly: -- pods -- services -- configmaps -- deployments -- replicasets -- horizontalpodautoscalers -- ingresses -- statefulsets - -The following RBAC permissions are required on the batch API group for the -following objects: - -- jobs -- cronjobs +```yaml +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: backstage-read-only +rules: + - apiGroups: + - '*' + resources: + - pods + - configmaps + - services + - deployments + - replicasets + - horizontalpodautoscalers + - ingresses + - statefulsets + - limitranges + verbs: + - get + - list + - watch + - apiGroups: + - batch + resources: + - jobs + - cronjobs + verbs: + - get + - list + - watch +``` ## Surfacing your Kubernetes components as part of an entity diff --git a/docs/features/kubernetes/installation.md b/docs/features/kubernetes/installation.md index 3b0895dd23..5b4e2fa716 100644 --- a/docs/features/kubernetes/installation.md +++ b/docs/features/kubernetes/installation.md @@ -62,13 +62,16 @@ add the following: import { KubernetesBuilder } from '@backstage/plugin-kubernetes-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; +import { CatalogClient } from '@backstage/catalog-client'; export default async function createPlugin( env: PluginEnvironment, ): Promise { + const catalogApi = new CatalogClient({ discoveryApi: env.discovery }); const { router } = await KubernetesBuilder.createBuilder({ logger: env.logger, config: env.config, + catalogApi, }).build(); return router; } diff --git a/docs/features/search/README.md b/docs/features/search/README.md index f1744d4d80..21deffb3a0 100644 --- a/docs/features/search/README.md +++ b/docs/features/search/README.md @@ -14,60 +14,20 @@ Backstage Search lets you find the right information you are looking for in the ## Features -- A federated, faceted search, searching across all entities registered in your Backstage instance. +- A search that lets you bring your own search engine. +- A search that lets you extend it by creating collators for easily indexing content from plugins and other sources. +- A search that lets you create composable search page experiences. +- A search that lets you customize the look and feel of each search result. -- A search that lets you plug in your own search engine of choice. - -- A standardized search API where you can choose to index data from other plugins. +See the more detailed [architecture](./architecture.md) and [tech stack](./architecture.md#tech-stack). ## Project roadmap -### Now - -**Backstage Search 1.0** - -A stable Search API for plugin developers to add search to their plugins, and app integrators to expose that to their users. - -We will consider Backstage Search to be 1.0 when the above -use-cases are met, and an ecosystem of search-enabled plugins are available and -stable. - -- As a plugin developer, there should be at least one example of a Backstage - plugin that integrates with search that I can use as inspiration for my own - plugin's search capabilities (for example, the TechDocs plugin). -- As an app integrator, there should be plenty of examples and documentation on - how to customize and extend search in my Backstage instance to meet my - organization's needs. - -### Next - -_Not specified_ - -### Someday/Maybe - -_Not specified_ - -### Done - -See [Done](#done) below for a list of completed roadmap items. +No current plans. ## Supported -The following sections show the search engines and plugins currently supported by Backstage Search. - -### Search engines - -See [Backstage Search Architecture](architecture.md) to get an overview of how -the search engines are used. - -| Search Engines | Support Status | -| -------------------------------------------------- | -------------- | -| [Lunr](./search-engines.md#lunr) | ✅ | -| [ElasticSearch](./search-engines.md#elasticsearch) | ✅ | -| [Postgres](./search-engines.md#postgres) | ✅ | - -[Reach out to us](#get-involved) if you want to chat about support for more -search engines. +The following sections show the plugins and search engines currently supported by Backstage Search. ### Plugins integrated with Backstage Search @@ -77,20 +37,19 @@ search engines. | [TechDocs](./how-to-guides.md#how-to-index-techdocs-documents) | ✅ | | [Stack Overflow](https://github.com/backstage/backstage/blob/master/plugins/stack-overflow-backend/README.md#index-stack-overflow-questions-to-search) | ✅ | -[Reach out to us](#get-involved) if you want to chat about support for more -plugins integrated to search. +### Search engines -## Tech Stack +See [Backstage Search Architecture](architecture.md) to get an overview of how +the search engines are used. -| Stack | Location | -| ------------------------- | ----------------------------------------------------- | -| Frontend Plugin | @backstage/plugin-search | -| Frontend Plugin Library | @backstage/plugin-search-react | -| Isomorphic Plugin Library | @backstage/plugin-search-common | -| Backend Plugin | @backstage/plugin-search-backend | -| Backend Plugin Library | @backstage/plugin-search-backend-node | -| Backend Plugin Module | @backstage/plugin-search-backend-module-elasticsearch | -| Backend Plugin Module | @backstage/plugin-search-backend-module-pg | +| Search Engines | Support Status | +| -------------------------------------------------- | -------------- | +| [ElasticSearch](./search-engines.md#elasticsearch) | ✅ | +| [Lunr](./search-engines.md#lunr) | ✅ | +| [Postgres](./search-engines.md#postgres) | Community ✅ | + +[Reach out to us](#get-involved) if you want to chat about support for more plugin integrations and +search engines. ## Get involved @@ -98,9 +57,9 @@ For any questions, feedback, or to help move search forward, reach out to us in the **#search** channel of our [Discord chatroom](https://github.com/backstage/backstage#community). -## Done +## Use Cases supported -**Backstage Search Pre-Alpha** +#### **Backstage Search Pre-Alpha** Search Frontend letting you search through the entities of the software catalog. @@ -118,7 +77,7 @@ there by means of a front-end only, non-extensible MVP. - As a software engineer I should be able to hide the filters if I don’t need to use them. -**Backstage Search Alpha** +#### **Backstage Search Alpha** Basic “out-of-the-box” in-memory indexing process of entities, and their metadata, registered to the Software Catalog. @@ -136,7 +95,7 @@ met, but built on top of a flexible, extensible platform. should be possible to have the pre-alpha user experiences covered without having to set up and configure a search engine. -**Backstage Search Beta** +#### **Backstage Search Beta** At least one production-ready search engine that supports the same use-cases as in the alpha. @@ -151,3 +110,18 @@ are met, and can be deployed using a production-ready search engine. - As an integrator, I should be able to tune the queries sent to my chosen search engine according to my organization's needs, but a sensible default query should be in place so that I am not required to do so. + +#### **Backstage Search 1.0** + +A stable Search API for plugin developers to add search to their plugins, and app integrators to expose that to their users. + +We will consider Backstage Search to be 1.0 when the above +use-cases are met, and an ecosystem of search-enabled plugins are available and +stable. + +- As a plugin developer, there should be at least one example of a Backstage + plugin that integrates with search that I can use as inspiration for my own + plugin's search capabilities (for example, the TechDocs plugin). +- As an app integrator, there should be plenty of examples and documentation on + how to customize and extend search in my Backstage instance to meet my + organization's needs. diff --git a/docs/features/search/architecture.md b/docs/features/search/architecture.md index 4fac0e7cff..f1183cec5f 100644 --- a/docs/features/search/architecture.md +++ b/docs/features/search/architecture.md @@ -4,10 +4,6 @@ title: Search Architecture description: Documentation on Search Architecture --- -> _This architecture has not been fully implemented yet. Find our milestones to -> follow our progress and help contribute on the -> [Search Roadmap](./README.md#project-roadmap)._ - Below you can explore the Search Architecture. Our aim with this architecture is to support a wide variety of search engines, while providing a simple developer experience for plugin developers, and a good out-of-the-box experience for @@ -44,3 +40,15 @@ Architecture non-goals: - At this time, we do not intend to directly support event-driven or incremental index management. Instead, we'll be focused on scheduled, bulk index management. + +## Tech Stack + +| Stack | Location | +| ------------------------- | ----------------------------------------------------- | +| Frontend Plugin | @backstage/plugin-search | +| Frontend Plugin Library | @backstage/plugin-search-react | +| Isomorphic Plugin Library | @backstage/plugin-search-common | +| Backend Plugin | @backstage/plugin-search-backend | +| Backend Plugin Library | @backstage/plugin-search-backend-node | +| Backend Plugin Module | @backstage/plugin-search-backend-module-elasticsearch | +| Backend Plugin Module | @backstage/plugin-search-backend-module-pg | diff --git a/docs/features/search/getting-started.md b/docs/features/search/getting-started.md index d0e13eda55..71b9c276d9 100644 --- a/docs/features/search/getting-started.md +++ b/docs/features/search/getting-started.md @@ -34,7 +34,7 @@ import { DefaultResultListItem, SearchFilter, } from '@backstage/plugin-search-react'; -import { CatalogResultListItem } from '@backstage/plugin-catalog'; +import { CatalogSearchResultListItem } from '@backstage/plugin-catalog'; export const searchPage = ( diff --git a/docs/features/search/how-to-guides.md b/docs/features/search/how-to-guides.md index fb0883d506..01d85b8aa2 100644 --- a/docs/features/search/how-to-guides.md +++ b/docs/features/search/how-to-guides.md @@ -148,271 +148,6 @@ indexBuilder.addCollator({ As shown above, you can add a catalog entity filter to narrow down what catalog entities are indexed by the search engine. -## How to migrate from Search Alpha to Beta - -For the purposes of this guide, Search Beta version is defined as: - -- **Search Plugin**: At least `v0.7.2` -- **Search Backend Plugin**: At least `v0.4.6` -- **Search Backend Node**: At least `v0.5.0` -- **Search Common**: At least `v0.3.0` - -In the Beta version, the Search Platform's indexing process has been rewritten -as a stream pipeline in order to improve efficiency and performance on large -sets of documents. - -If you've not yet extended the Search Platform with custom code, and have -instead taken advantage of default collators, decorators, and search engines -provided by existing plugins, the migration process is fairly straightforward: - -1. Upgrade to at least version `0.5.0` of - `@backstage/plugin-search-backend-node`, as well as any backend plugins whose - collators you are using (e.g. at least version `0.23.0` of - `@backstage/plugin-catalog-backend` and/or version `0.14.1` of - `@backstage/plugin-techdocs-backend`), as well as any search-engine specific - plugin you are using (e.g. at least version `0.3.0` of - `@backstage/plugin-search-backend-module-pg` or version `0.1.0` of - `@backstage/plugin-search-backend-module-elasticsearch`). -2. Then, make the following changes to your - `/packages/backend/src/plugins/search.ts` file: - - ```diff - -import { DefaultCatalogCollator } from '@backstage/plugin-catalog-backend'; - -import { DefaultTechDocsCollator } from '@backstage/plugin-techdocs-backend'; - +import { DefaultCatalogCollatorFactory } from '@backstage/plugin-catalog-backend'; - +import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backend'; - // ... - const indexBuilder = new IndexBuilder({ logger: env.logger, searchEngine }); - indexBuilder.addCollator({ - defaultRefreshIntervalSeconds: 600, - - collator: DefaultCatalogCollator.fromConfig(env.config, { - discovery: env.discovery, - }), - + factory: DefaultCatalogCollatorFactory.fromConfig(env.config, { - discovery: env.discovery, - }), - }); - indexBuilder.addCollator({ - defaultRefreshIntervalSeconds: 600, - - collator: DefaultTechDocsCollator.fromConfig(env.config, { - + factory: DefaultTechDocsCollatorFactory.fromConfig(env.config, { - discovery: env.discovery, - logger: env.logger, - }), - }); - ``` - -Any custom collators, decorators, or search engine implementations will require -minor refactoring. Continue on for details. - -### Rewriting alpha-style collators for beta - -In alpha versions of the Backstage Search Platform, collators were classes that -implemented an `execute` method which resolved an `IndexableDocument` array. - -In beta versions, the logic encapsulated by the aforementioned `execute` method -is contained within an [object-mode][obj-mode] `Readable` stream where each -object pushed onto the stream is of type `IndexableDocument`. Instances of this -stream are instantiated by a factory class conforming to the -`DocumentCollatorFactory` interface. - -The optimal conversion strategy will vary depending on the collator's logic, but -the simplest conversion can follow a process like this: - -1. Rename your collator class to something like `YourCollatorFactory` and update - it to implement `DocumentCollatorFactory` instead of `DocumentCollator`. -2. Update its `execute` method so that it resolves - `AsyncGenerator` instead of `YourIndexableDocument[]`. -3. Implement `DocumentCollatorFactory`'s `getCollator` method which resolves to - `Readable.from(this.execute())` (which is a utility for creating [readable - streams][read-stream] from [async generators][async-gen]). - -```ts -import { DocumentCollatorFactory } from '@backstage/plugin-search-backend-node'; -import { Readable } from 'stream'; -export class YourCollatorFactory implements DocumentCollatorFactory { - public readonly type: string = 'your-type'; - async *execute(): AsyncGenerator { - const widgets = await this.client.getWidgets(); - for (const widget of widgets) { - yield { - title: widget.name, - location: widget.url, - text: widget.description, - }; - } - } - async getCollator() { - return Readable.from(this.execute()); - } -} -``` - -Note: it may be possible to simplify your collator dramatically! If your custom -collator was previously using streams under the hood (for example, by reading -newline delimited JSON from a local or remote file), you could just expose the -stream directly via a simple factory class: - -```ts -import { DocumentCollatorFactory } from '@backstage/plugin-search-backend-node'; -import { createReadStream } from 'fs'; -import { parse } from '@jsonlines/core'; -export class YourCollatorFactory implements DocumentCollatorFactory { - public readonly type: string = 'your-type'; - async getCollator() { - const parseStream = parse(); - return createReadStream('./documents.ndjson').pipe(parseStream); - } -} -``` - -### Rewriting alpha-style decorators for beta - -In alpha versions of the Backstage Search Platform, decorators were classes that -implemented an `execute` method which took an `IndexableDocument` array as an -argument, and resolved a modified array of the same type. - -In beta versions, the logic encapsulated by the aforementioned `execute` method -is contained within an object-mode `Transform` stream which reads objects of -type `IndexableDocument`, and writes objects of a conforming type. Similar to -collators, instances of this stream are instantiated by a factory class -conforming to the `DocumentDecoratorFactory` interface. - -Although you can choose to implement a `Transform` stream from scratch, the -`@backstage/plugin-search-backend-node` package provides a `DecoratorBase` class -in order to simplify the developer experience. With this base class, all that's -needed is to transfer your old decorator class logic into the base class' three -methods (`initialize`, `decorate`, and `finalize`), and implement the factory -class that instantiates the stream: - -```ts -import { DecoratorBase } from '@backstage/plugin-search-backend-node'; -export class YourDecorator extends DecoratorBase { - async initialize() { - // Setup logic. Performed once before any documents are consumed. - } - async decorate( - document: YourIndexableDocument, - ): Promise { - // Perform transformation logic here. - return document; - } - async finalize() { - // Teardown logic. Performed once after all documents have been consumed. - } -} -export class YourDecoratorFactory implements DocumentDecoratorFactory { - async getDecorator() { - return new YourDecorator(); - } -} -``` - -Note the return type of the `decorate` method and how each can be used to -different effect. - -- By resolving a single `YourIndexableDocument` object, your decorator can be - used to make simple transformations: - - ```ts - class BooleanWidgetCoolnessDecorator extends DecoratorBase { - async decorator(widget) { - // Perform a simple, 1:1 transformation. - widget.isCool = widget.isCool === 'true' ? true : false; - return widget; - } - } - ``` - -- By resolving `undefined`, your decorator can filter out documents which - shouldn't be in the index: - - ```ts - class OnlyCoolWidgetsDecorator extends DecoratorBase { - async decorator(widget) { - // Perform a simple filter operation. - return widget.isCool ? widget : undefined; - } - } - ``` - -- By resolving an array of `YourIndexableDocument` objects, you can generate - multiple documents based on the content of one: - - ```ts - class WidgetByVariantDecorator extends DecoratorBase { - async decorator(widget) { - // Generate one widget doc per widget variant. - return widget.variants.map(variant => { - // Each widget doc is the given widget plus a "variant" property - // pulled from a widget.variants string array. - return { - ...widget, - variant, - }; - }); - } - } - ``` - -In alpha versions, a decorator had access to every `IndexableDocument` -simultaneously. This is no longer possible in beta versions (precisely to make -the indexing process more efficient and performant). You will need to modify -your decorator's logic so that it does not need access to every document at -once. - -### Rewriting alpha-style search engines for beta - -Search Engines are responsible for both querying and indexing documents to an -underlying search engine technology. While the search engine query interface -didn't change between alpha and beta versions, the indexing half of the -interface _did_ change. - -In alpha versions of the Backstage Search Platform, a search engine implemented -an `index` method which took a `type` and an `IndexableDocument` array and was -responsible for writing these documents to the underlying search engine. - -In beta versions, the logic encapsulated by the aforementioned `index` method is -contained within an object-mode `Writable` stream which expects objects of type -`IndexableDocument`. On the search engine class itself, the `index` method is -replaced with a `getIndexer` factory method which still takes the `type`, but -resolves an instance of the aforementioned `Writable` stream. - -Although you can choose to implement a `Writable` stream from scratch, the -`@backstage/plugin-search-backend-node` package provides a -`BatchSearchEngineIndexer` class in order to simplify the developer experience. -With this base class, which collects documents in batches of a configurable size -on your behalf, all that's needed is to transfer your old `index` method logic -into the base class' three methods (`initialize`, `index`, and `finalize`), and -implement the factory method that instantiates the stream: - -```ts -import { BatchSearchEngineIndexer } from '@backstage/plugin-search-backend-node'; -import { SearchEngine } from '@backstage/plugin-search-common'; -export class YourSearchEngineIndexer extends BatchSearchEngineIndexer { - constructor({ type }: { type: string }) { - // Customize the number of documents passed to the index method per batch. - super({ batchSize: 500 }); - // An imaginary search engine indexing client. - this.index = new SomeSearchEngineIndex({ indexName: type }); - } - async initialize() { - // Setup logic. Performed once before any documents are consumed. - } - async index(documents: IndexableDocument[]) { - await this.index.batchOf(documents); - } - async finalize() { - // Teardown logic. Performed once after all documents have been consumed. - } -} -export class YourSearchEngine implements SearchEngine { - async getIndexer(type: string) { - return new YourSearchEngineIndexer({ type }); - } -} -``` - ## How to customize search results highlighting styling The default highlighting styling for matched terms in search results is your diff --git a/docs/features/search/search-engines.md b/docs/features/search/search-engines.md index ecd8a85109..515c1268d7 100644 --- a/docs/features/search/search-engines.md +++ b/docs/features/search/search-engines.md @@ -232,3 +232,23 @@ search: auth: apiKey: base64EncodedKey ``` + +### Elastic search batch size + +Default batch size of the elastic search engine is set to 1000. If you are using a lower spec computing resources (like AWS small instance), +you may get an error caused by limited `thread_pool` configuration. ( `429 Too Many Requests /_bulk` ) + +In this case you need to decrease the batch size to index the resources to prevent this kind of error. You can easily decrease +or increase the batch size in your `app-config.yaml` using the `batchSize` option provided for elasticsearch configuration. + +#### Configuration example + +**Set batch size to 100** + +```yaml +search: + elasticsearch: + batchSize: 100 +``` + +> You can also increase the batch size if you are using a large ES instance. diff --git a/docs/features/software-catalog/external-integrations.md b/docs/features/software-catalog/external-integrations.md index 30bd4c77bc..40f917e2f3 100644 --- a/docs/features/software-catalog/external-integrations.md +++ b/docs/features/software-catalog/external-integrations.md @@ -377,6 +377,10 @@ import { export class SystemXReaderProcessor implements CatalogProcessor { constructor(private readonly reader: UrlReader) {} + getProcessorName(): string { + return 'SystemXReaderProcessor'; + } + async readLocation( location: LocationSpec, _optional: boolean, diff --git a/docs/features/techdocs/README.md b/docs/features/techdocs/README.md index 65cfafd464..3251451cce 100644 --- a/docs/features/techdocs/README.md +++ b/docs/features/techdocs/README.md @@ -30,16 +30,15 @@ Today, it is one of the core products in Spotify’s developer experience offeri ### Now -With the Backstage 1.2 release, we have introduced the [TechDocs Addon Framework](https://backstage.io/blog/2022/05/13/techdocs-addon-framework) for augmenting the TechDocs experience at read-time. - -In addition to the framework itself, we have open sourced a **ReportIssue** Addon, helping you to create a feedback loop that drives up documentation quality and foster a documentation culture at your organization. +No current plans. ### Next -What can we do in TechDocs to help drive up documentation quality? We have many ideas, for example, a Trust Card with associated Trust Score and automatic triggering of documentation maintenance notifications. +No current plans. ### Someday/Maybe +- What can we do in TechDocs to help drive up documentation quality? We have many ideas, for example, a Trust Card with associated Trust Score and automatic triggering of documentation maintenance notifications. - Contribute to and deploy from a marketplace of TechDocs Addons - Addon: MDX (allows you to use JSX in your Markdown content) - Can we go static site generator agnostic? @@ -129,3 +128,9 @@ TechDocs packages: - @backstage/plugin-techdocs-backend - @backstage/plugin-techdocs-node - @techdocs/cli + +**TechDocs Addon Framework** + +With the Backstage 1.2 release, we introduced the [TechDocs Addon Framework](https://backstage.io/blog/2022/05/13/techdocs-addon-framework) for augmenting the TechDocs experience at read-time. + +In addition to the framework itself, we open sourced a **ReportIssue** Addon, helping you to create a feedback loop that drives up documentation quality and foster a documentation culture at your organization. diff --git a/docs/features/techdocs/cli.md b/docs/features/techdocs/cli.md index 52c389975e..dc89f1718b 100644 --- a/docs/features/techdocs/cli.md +++ b/docs/features/techdocs/cli.md @@ -83,6 +83,8 @@ Serve a documentation project locally in a Backstage app-like environment Options: -i, --docker-image The mkdocs docker container to use (default: "spotify/techdocs") --docker-entrypoint Override the image entrypoint + --docker-option Extra options to pass to the docker run command, e.g. "--add-host=internal.host:192.168.11.12" + (can be added multiple times). --no-docker Do not use Docker, use MkDocs executable in current user environment. --mkdocs-port Port for MkDocs server to use (default: "8000") -v --verbose Enable verbose output. (default: false) diff --git a/docs/features/techdocs/getting-started.md b/docs/features/techdocs/getting-started.md index f8bf98c0e0..c2070e7840 100644 --- a/docs/features/techdocs/getting-started.md +++ b/docs/features/techdocs/getting-started.md @@ -278,10 +278,7 @@ Note: We recommend Python version 3.7 or higher. > Caveat: Please install the `mkdocs-techdocs-core` package after all other > Python packages. The order is important to make sure we get correct version of -> some of the dependencies. For example, we want `Markdown` version to be -> [3.2.2](https://github.com/backstage/backstage/blob/f9f70c225548017b6a14daea75b00fbd399c11eb/packages/techdocs-container/techdocs-core/requirements.txt#L11). -> You can also explicitly install `Markdown==3.2.2` after installing all other -> Python packages. +> some of the dependencies. ## Running Backstage locally diff --git a/docs/getting-started/app-custom-theme.md b/docs/getting-started/app-custom-theme.md index 1a6658f0b2..25131f1c91 100644 --- a/docs/getting-started/app-custom-theme.md +++ b/docs/getting-started/app-custom-theme.md @@ -136,15 +136,27 @@ const myTheme = createTheme({ fontFamily: 'Comic Sans MS', /* below drives the header colors */ pageTheme: { - home: genPageTheme(['#8c4351', '#343b58'], shapes.wave), - documentation: genPageTheme(['#8c4351', '#343b58'], shapes.wave2), - tool: genPageTheme(['#8c4351', '#343b58'], shapes.round), - service: genPageTheme(['#8c4351', '#343b58'], shapes.wave), - website: genPageTheme(['#8c4351', '#343b58'], shapes.wave), - library: genPageTheme(['#8c4351', '#343b58'], shapes.wave), - other: genPageTheme(['#8c4351', '#343b58'], shapes.wave), - app: genPageTheme(['#8c4351', '#343b58'], shapes.wave), - apis: genPageTheme(['#8c4351', '#343b58'], shapes.wave), + home: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + documentation: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave2, + }), + tool: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.round }), + service: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave, + }), + website: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave, + }), + library: genPageTheme({ + colors: ['#8c4351', '#343b58'], + shape: shapes.wave, + }), + other: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + app: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), + apis: genPageTheme({ colors: ['#8c4351', '#343b58'], shape: shapes.wave }), }, }); ``` @@ -261,6 +273,126 @@ const LogoFull = () => { }; ``` +## Icons + +So far you've seen how to create your own theme and add your own logo, in the following sections you'll be shown how to override the existing icons and how to add more icons + +### Custom Icons + +You can also customize the Project's _default_ icons. + +You can change the following [icons](https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/icons.tsx). + +#### Requirements + +- Files in `.svg` format +- React components created for the icons + +#### Create React Component + +In your front-end application, locate the `src` folder. We suggest creating the `assets/icons` directory and `CustomIcons.tsx` file. + +> Another example [here](https://github.com/backstage/backstage/blob/master/plugins/azure-devops/src/components/AzurePipelinesIcon/AzurePipelinesIcon.tsx), if you want to ensure proper behavior in light and dark themes. + +```tsx +// customIcons.tsx +import { SvgIcon, SvgIconProps } from '@material-ui/core'; + +import React from 'react'; + +export const ExampleIcon = (props: SvgIconProps) => ( + + + +); +``` + +#### Using the custom icon + +Supply your custom icon in `packages/app/src/App.tsx` + +```diff + ++ import { ExampleIcon } from './assets/customIcons' + +[...] + +const app = createApp({ + apis, + components: { + [...] + }, + themes: [ + [...] + ], ++ icons: { ++ github: ExampleIcon, ++ }, + bindRoutes({ bind }) { + [...] + } +}) + +[...] +``` + +### Adding Icons + +You can add more icons, if the [default icons](https://github.com/backstage/backstage/blob/master/packages/app-defaults/src/defaults/icons.tsx) do not fit your needs, so that they can be used in other places like for Links in your entities. For this example we'll be using icons from[Material UI](https://v4.mui.com/components/material-icons/) and specifically the `AlarmIcon`. Here's how to do that: + +1. First you will want to open your `App.tsx` in `/packages/app/src` +2. Then you want to import your icon, add this to the rest of your imports: `import AlarmIcon from '@material-ui/icons/Alarm';` +3. Next you want to add the icon like this to your `createApp`: + + ```diff + const app = createApp({ + apis: ..., + plugins: ..., + + icons: { + + alert: AlarmIcon, + + }, + themes: ..., + components: ..., + }); + ``` + +4. Now we can reference `alert` for our icon in our entity links like this: + + ```yaml + apiVersion: backstage.io/v1alpha1 + kind: Component + metadata: + name: artist-lookup + description: Artist Lookup + links: + - url: https://example.com/alert + title: Alerts + icon: alert + ``` + + And this is the result: + + ![Example Link with Alert icon](../assets/getting-started/add-icons-links-example.png) + + Another way you can use these icons is from the `AppContext` like this: + + ```ts + import { useApp } from '@backstage/core-plugin-api'; + + const app = useApp(); + const alertIcon = app.getSystemIcon('alert'); + ``` + + You might want to use this method if you have an icon you want to use in several locations. + +Note: If the icon is not available as one of the default icons or one you've added then it will fall back to Material UI's `LanguageIcon` + ## Custom Homepage In addition to a custom theme, a custom logo, you can also customize the diff --git a/docs/integrations/aws-s3/discovery.md b/docs/integrations/aws-s3/discovery.md index 40739937a4..9e9e6ebede 100644 --- a/docs/integrations/aws-s3/discovery.md +++ b/docs/integrations/aws-s3/discovery.md @@ -76,27 +76,3 @@ builder.addEntityProvider( }), ); ``` - -## Alternative Processor - -As alternative to the entity provider `AwsS3EntityProvider` -you can still use the `AwsS3DiscoveryProcessor`. - -```yaml -# app-config.yaml - -catalog: - locations: - - type: s3-discovery - target: https://sample-bucket.s3.us-east-2.amazonaws.com/prefix/ -``` - -```ts -/* packages/backend/src/plugins/catalog.ts */ - -import { AwsS3DiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-aws'; - -const builder = await CatalogBuilder.create(env); -/** ... other processors ... */ -builder.addProcessor(new AwsS3DiscoveryProcessor(env.reader)); -``` diff --git a/docs/integrations/azure/org.md b/docs/integrations/azure/org.md index 56d37369dd..99c517b568 100644 --- a/docs/integrations/azure/org.md +++ b/docs/integrations/azure/org.md @@ -96,7 +96,7 @@ To authenticate with a certificate rather than a client secret, you can set the If deploying to resources that supports Managed Identity, and has identities configured (e.g. Azure App Services, Azure Container Apps), Managed Identity should be picked up without any additional configuration. If your app has multiple managed identities, you may need to set the `AZURE_CLIENT_ID` environment variable to tell Azure Identity which identity to use. -You will need to grant the same permissions to your identity as described for App Registrations above. +To grant the managed identity the same permissions as mentioned in _App Registration_ above, [please follow this guide](https://docs.microsoft.com/en-us/azure/app-service/tutorial-connect-app-access-microsoft-graph-as-app-javascript?tabs=azure-powershell) ## Filtering imported Users and Groups diff --git a/docs/integrations/bitbucket/discovery.md b/docs/integrations/bitbucket/discovery.md index 285b7cc78b..15ede69a4a 100644 --- a/docs/integrations/bitbucket/discovery.md +++ b/docs/integrations/bitbucket/discovery.md @@ -41,7 +41,7 @@ And then add the processor to your catalog builder: ## Self-hosted Bitbucket Server To use the discovery processor with a self-hosted Bitbucket Server, you'll need -a Bitbucket integration [set up](locations.md) with a `BITBUCKET_TOKEN` and a +a Bitbucket integration [set up](../bitbucketServer/locations.md) with a `BITBUCKET_TOKEN` and a `BITBUCKET_API_BASE_URL`. Then you can add a location target to the catalog configuration: @@ -74,7 +74,7 @@ The target is composed of four parts: ## Bitbucket Cloud To use the discovery processor with Bitbucket Cloud, you'll need a Bitbucket -integration [set up](locations.md) with a `username` and an `appPassword`. Then +integration [set up](../bitbucketCloud/locations.md) with a `username` and an `appPassword`. Then you can add a location target to the catalog configuration: ```yaml diff --git a/docs/integrations/bitbucket/locations.md b/docs/integrations/bitbucket/locations.md deleted file mode 100644 index 878030a29c..0000000000 --- a/docs/integrations/bitbucket/locations.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -id: locations -title: Bitbucket Locations -sidebar_label: Locations -# prettier-ignore -description: Integrating source code stored in Bitbucket into the Backstage catalog ---- - -The Bitbucket integration supports loading catalog entities from bitbucket.org (Bitbucket Cloud) -or Bitbucket Server. Entities can be added to -[static catalog configuration](../../features/software-catalog/configuration.md), -or registered with the -[catalog-import](https://github.com/backstage/backstage/tree/master/plugins/catalog-import) -plugin. - -## Bitbucket Cloud - -Please see [the Bitbucket Cloud documentation](../bitbucketCloud/locations.md). - -## Bitbucket Server - -```yaml -integrations: - bitbucketServer: - - host: bitbucket.company.com - token: ${BITBUCKET_SERVER_TOKEN} -``` - -Directly under the `bitbucketServer` key is a list of provider configurations, where -you can list the Bitbucket Server providers you want to fetch data from. Each entry is -a structure with the following elements: - -- `host`: The host of the Bitbucket Server instance, e.g. `bitbucket.company.com`. -- `token` (optional): - An [personal access token](https://confluence.atlassian.com/bitbucketserver/personal-access-tokens-939515499.html) - as expected by Bitbucket Server. -- `apiBaseUrl` (optional): The URL of the Bitbucket Server API. For self-hosted - installations, it is commonly at `https:///rest/api/1.0`. diff --git a/docs/integrations/bitbucketServer/discovery.md b/docs/integrations/bitbucketServer/discovery.md new file mode 100644 index 0000000000..57e52d1dae --- /dev/null +++ b/docs/integrations/bitbucketServer/discovery.md @@ -0,0 +1,114 @@ +--- +id: discovery +title: Bitbucket Server Discovery +sidebar_label: Discovery +# prettier-ignore +description: Automatically discovering catalog entities from repositories in Bitbucket Server +--- + +The Bitbucket Server integration has a special entity provider for discovering +catalog files located in Bitbucket Server. +The provider will search your Bitbucket Server account and register catalog files matching the configured path +as Location entity and via following processing steps add all contained catalog entities. +This can be useful as an alternative to static locations or manually adding things to the catalog. + +## Installation + +You will have to add the entity provider in the catalog initialization code of your +backend. The provider is not installed by default, therefore you have to add a +dependency to `@backstage/plugin-catalog-backend-module-bitbucket-server` to your backend +package. + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-bitbucket-server +``` + +And then add the entity provider to your catalog builder: + +```diff + // In packages/backend/src/plugins/catalog.ts ++ import { BitbucketServerEntityProvider } from '@backstage/plugin-catalog-backend-module-bitbucket-server'; + + export default async function createPlugin( + env: PluginEnvironment, + ): Promise { + const builder = await CatalogBuilder.create(env); ++ builder.addEntityProvider( ++ BitbucketServerEntityProvider.fromConfig(env.config, { ++ logger: env.logger, ++ schedule: env.scheduler.createScheduledTaskRunner({ ++ frequency: { minutes: 30 }, ++ timeout: { minutes: 3 }, ++ }), ++ }), ++ ); + + // [...] + } +``` + +## Configuration + +To use the entity provider, you'll need a [Bitbucket Server integration set up](locations.md). + +Additionally, you need to configure your entity provider instance(s): + +```yaml +# app-config.yaml + +catalog: + providers: + bitbucketServer: + yourProviderId: # identifies your ingested dataset + host: 'bitbucket.mycompany.com' + catalogPath: /catalog-info.yaml # default value + filters: # optional + projectKey: '^apis-.*$' # optional; RegExp + repoSlug: '^service-.*$' # optional; RegExp +``` + +- **host**: + The host of the Bitbucket Server instance, **note**: the host needs to registered as an integration as well, see [location](locations.md). +- **`catalogPath`** _(optional)_: + Default: `/catalog-info.yaml`. + Path where to look for `catalog-info.yaml` files. + When started with `/`, it is an absolute path from the repo root. +- **filters** _(optional)_: + - **`projectKey`** _(optional)_: + Regular expression used to filter results based on the project key. + - **repoSlug** _(optional)_: + Regular expression used to filter results based on the repo slug. + +## Custom location processing + +The Bitbucket Server Entity Provider will by default emit a location for each +matching repository. However, it is possible to override this functionality and take full control of how each +matching repository is processed. + +`BitbucketServerEntityProvider.fromConfig` takes an optional parameter +`options.parser` where you can set your own parser to be used for each matched +repository. + +```typescript +const provider = BitbucketServerEntityProvider.fromConfig(env.config, { + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + parser: async function* customLocationParser(options: { + location: LocationSpec, + client: BitbucketServerClient, + }) { + // Custom logic for interpreting the matching repository + // See defaultBitbucketServerLocationParser for an example + } +); +``` + +## Alternative + +_Deprecated!_ Please raise issues for use cases not covered by the entity provider. + +[You can use the `BitbucketDiscoveryProcessor`.](../bitbucket/discovery.md#self-hosted-bitbucket-server) diff --git a/docs/integrations/bitbucketServer/locations.md b/docs/integrations/bitbucketServer/locations.md new file mode 100644 index 0000000000..7ff19b8b27 --- /dev/null +++ b/docs/integrations/bitbucketServer/locations.md @@ -0,0 +1,51 @@ +--- +id: locations +title: Bitbucket Server Locations +sidebar_label: Locations +# prettier-ignore +description: Integrating source code stored in Bitbucket Server into the Backstage catalog +--- + +The Bitbucket Server integration supports loading catalog entities from Bitbucket Server. +Entities can be added to +[static catalog configuration](../../features/software-catalog/configuration.md), +or registered with the +[catalog-import](https://github.com/backstage/backstage/tree/master/plugins/catalog-import) +plugin. + +## Configuration + +```yaml +integrations: + bitbucketServer: + - host: bitbucket.mycompany.com + apiBaseUrl: https://bitbucket.mycompany.com/rest/api/1.0 + token: ${BITBUCKET_SERVER_TOKEN} +``` + +or with Basic Auth + +```yaml +integrations: + bitbucketServer: + - host: bitbucket.company.com + apiBaseUrl: https://bitbucket.mycompany.com/rest/api/1.0 + username: ${BITBUCKET_SERVER_USERNAME} + password: ${BITBUCKET_SERVER_PASSWORD} +``` + +Directly under the `bitbucketServer` key is a list of provider configurations, where +you can list the Bitbucket Server providers you want to fetch data from. Each entry is +a structure with the following elements: + +- `host`: The host of the Bitbucket Server instance, e.g. `bitbucket.mycompany.com`. +- `token` (optional): + A [personal access token](https://confluence.atlassian.com/bitbucketserver/personal-access-tokens-939515499.html) + as expected by Bitbucket Server. +- `username` (optional): + use for [Basic Auth](https://developer.atlassian.com/server/bitbucket/how-tos/command-line-rest/#authentication) for Bitbucket Server. +- `password` (optional): + use for [Basic Auth](https://developer.atlassian.com/server/bitbucket/how-tos/command-line-rest/#authentication) for Bitbucket Server. + Note: a token can also be used as a substitute for the password, see [HTTP access tokens](https://confluence.atlassian.com/bitbucketserver/personal-access-tokens-939515499.html). +- `apiBaseUrl` (optional): The URL of the Bitbucket Server API. For self-hosted + installations, it is commonly at `https:///rest/api/1.0`. diff --git a/docs/integrations/github/discovery.md b/docs/integrations/github/discovery.md index a0c3fed153..339a1e2ca3 100644 --- a/docs/integrations/github/discovery.md +++ b/docs/integrations/github/discovery.md @@ -6,6 +6,125 @@ sidebar_label: Discovery description: Automatically discovering catalog entities from repositories in a GitHub organization --- +## GitHub Provider + +The GitHub integration has a discovery provider for discovering catalog +entities within a GitHub organization. The provider will crawl the GitHub +organization and register entities matching the configured path. This can be +useful as an alternative to static locations or manually adding things to the +catalog. This is the prefered method for ingesting entities into the catalog. + +## Installation + +You will have to add the provider in the catalog initialization code of your +backend. They are not installed by default, therefore you have to add a +dependency on `@backstage/plugin-catalog-backend-module-github` to your backend +package. + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-github +``` + +And then add the entity provider to your catalog builder: + +```diff + // In packages/backend/src/plugins/catalog.ts ++ import { GitHubEntityProvider } from '@backstage/plugin-catalog-backend-module-github'; + + export default async function createPlugin( + env: PluginEnvironment, + ): Promise { + const builder = await CatalogBuilder.create(env); ++ builder.addEntityProvider( ++ GitHubEntityProvider.fromConfig(env.config, { ++ logger: env.logger, ++ schedule: env.scheduler.createScheduledTaskRunner({ ++ frequency: { minutes: 30 }, ++ timeout: { minutes: 3 }, ++ }), ++ }), ++ ); + + // [...] + } +``` + +## Configuration + +To use the discovery provider, you'll need a GitHub integration +[set up](locations.md) with either a [Personal Access Token](../../getting-started/configuration.md#setting-up-a-github-integration) or [GitHub Apps](./github-apps.md). + +Then you can add a github config to the catalog providers configuration: + +```yaml +catalog: + providers: + github: + # the provider ID can be any camelCase string + providerId: + organization: 'backstage' # string + catalogPath: '/catalog-info.yaml' # string + filters: + branch: 'main' # string + repository: '.*' # Regex + customProviderId: + organization: 'new-org' # string + catalogPath: '/custom/path/catalog-info.yaml' # string + filters: # optional filters + branch: 'develop' # optional string + repository: '.*' # optional Regex + wildcardProviderId: + organization: 'new-org' # string + catalogPath: '/groups/**/*.yaml' # this will search all folders for files that end in .yaml + filters: # optional filters + branch: 'develop' # optional string + repository: '.*' # optional Regex +``` + +This provider supports multiple organizations via unique provider IDs. + +> **Note:** It is possible but certainly not recommended to skip the provider ID level. +> If you do so, `default` will be used as provider ID. + +- **`catalogPath`** _(optional)_: + Default: `/catalog-info.yaml`. + Path where to look for `catalog-info.yaml` files. + You can use wildcards - `*` or `**` - to search the path and/or the filename +- **filters** _(optional)_: + - **branch** _(optional)_: + String used to filter results based on the branch name. + - **repository** _(optional)_: + Regular expression used to filter results based on the repository name. +- **organization**: + Name of your organization account/workspace. + If you want to add multiple organizations, you need to add one provider config each. + +## GitHub API Rate Limits + +GitHub [rate limits](https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting) API requests to 5,000 per hour (or more for Enterprise +accounts). The snippet below refreshes the Backstage catalog data every 35 minutes, which issues an API request for each discovered location. + +If your requests are too frequent then you may get throttled by +rate limiting. You can change the refresh frequency of the catalog in your `packages/backend/src/plugins/catalog.ts` file: + +```typescript +schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 35 }, + timeout: { minutes: 30 }, +}), +``` + +More information about scheduling can be found on the [TaskScheduleDefinition](https://backstage.io/docs/reference/backend-tasks.taskscheduledefinition) page. + +Alternatively, or additionally, you can configure [github-apps](github-apps.md) authentication +which carries a much higher rate limit at GitHub. + +This is true for any method of adding GitHub entities to the catalog, but +especially easy to hit with automatic discovery. + +## GitHub Processor (To Be Deprecated) + The GitHub integration has a special discovery processor for discovering catalog entities within a GitHub organization. The processor will crawl the GitHub organization and register entities matching the configured path. This can be diff --git a/docs/integrations/gitlab/discovery.md b/docs/integrations/gitlab/discovery.md index aad73c8209..df5aadcab4 100644 --- a/docs/integrations/gitlab/discovery.md +++ b/docs/integrations/gitlab/discovery.md @@ -24,6 +24,7 @@ catalog: branch: main # Optional. Uses `master` as default group: example-group # Optional. Group and subgroup (if needed) to look for repositories. If not present the whole project will be scanned entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml` + projectPattern: /[\s\S]*/ # Optional. Filters found projects based on provided patter. Defaults to `/[\s\S]*/`, what means to not filter anything ``` As this provider is not one of the default providers, you will first need to install diff --git a/docs/integrations/google-cloud-storage/locations.md b/docs/integrations/google-cloud-storage/locations.md index e15cb6346c..1f0334ff17 100644 --- a/docs/integrations/google-cloud-storage/locations.md +++ b/docs/integrations/google-cloud-storage/locations.md @@ -36,6 +36,13 @@ Then make sure the environment variables `GCS_CLIENT_EMAIL` and Since this integration uses the Google Storage SDK, you can also choose to not provide any explicit credentials and let the SDK discover them automatically. +Please note that for this method to work you must add an empty `googleGcs` object to the `integrations` section in `app-config.yaml`. + +```yaml +integrations: + googleGcs: {} +``` + One of these discovery methods is to provide an environment variable called `GOOGLE_APPLICATION_CREDENTIALS` and set it to the file path of your JSON service account key. diff --git a/docs/local-dev/cli-build-system.md b/docs/local-dev/cli-build-system.md index 9245cea7ff..cc364d0ca5 100644 --- a/docs/local-dev/cli-build-system.md +++ b/docs/local-dev/cli-build-system.md @@ -38,7 +38,7 @@ In addition, there are a number of hard and soft requirements: - Scale - It should scale to hundreds of large packages without excessive wait times - Reloads - The development flow should support quick on-save hot reloads -- Simple - Usage should simple and configuration should be kept minimal +- Simple - Usage should be simple and configuration should be kept minimal - Universal - Development towards both web applications, isomorphic packages, and Node.js - Modern - The build system targets modern environments @@ -95,7 +95,7 @@ These are the available roles that are currently supported by the Backstage buil | Role | Description | Example | | ---------------------- | -------------------------------------------- | -------------------------------------------- | -| frontend | Bundled frontend application | `package/app` | +| frontend | Bundled frontend application | `packages/app` | | backend | Bundled backend application | `packages/backend` | | cli | Package used as a command-line interface | `@backstage/cli`, `@backstage/codemods` | | web-library | Web library for use by other packages | `@backstage/plugin-catalog-react` | diff --git a/docs/overview/roadmap.md b/docs/overview/roadmap.md index df242ed172..2763f95a5a 100644 --- a/docs/overview/roadmap.md +++ b/docs/overview/roadmap.md @@ -12,12 +12,12 @@ and the broader Backstage community. The Backstage roadmap lays out both [“what's next”](#whats-next) and ["future work"](#future-work). With "next" we mean features planned for release within -the ongoing quarter from April through June 2022. With "future" we mean +the ongoing quarter from July through September 2022. With "future" we mean features on the radar, but not yet scheduled. -| [What's next](#whats-next) | [Future work](#future-work) | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | -| [Backstage Search 1.0](#search-1.0)
[Backend Services (MVP)](#backend-services-mvp)
[Backstage Security Audit](#backstage-security-audit)
[Backstage Threat Model](#backstage-threat-model)
[TechDocs Addon Framework](#techdocs-addon-framework)
[Software Catalog pagination](#software-catalog-pagination)
[More SIGs](#more-sigs) | Ease of onboarding
Composable Homepage 1.0
Creator experience
GraphQL
Telemetry | +| [What's next](#whats-next) | [Future work](#future-work) | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | +| [Backend Services (MVP)](#backend-services-mvp)
[Backstage Security Audit](#backstage-security-audit)
[Backstage Threat Model](#backstage-threat-model)
[Software Catalog pagination](#software-catalog-pagination)
[More SIGs](#more-sigs) | Ease of onboarding
Composable Homepage 1.0
Creator experience
GraphQL
Telemetry | The long-term roadmap (12 - 36 months) is not detailed in the public roadmap. Third-party contributions are also not currently included in the roadmap. Let us @@ -30,10 +30,6 @@ The feature set below is planned for the ongoing quarter, and grouped by theme. The list order doesn't necessarily reflect priority, and the development/release cycle will vary based on maintainer schedules. -### Backstage Search 1.0 - -Fix the few remaining issues to get Backstage Search platform up to 1.0. For more information, see the [Backstage Search documentation and roadmap page](https://backstage.io/docs/features/search/search-overview). - ### Backend Services (MVP) To better scale and maintain the Backstage instances, a backend services system @@ -72,14 +68,6 @@ The planned artifacts are: - Concise high level threat model that will be included as part of the Backstage security documentation. - Granular threat model created in conjunction with the security audit to inform further security investment areas for Backstage. -### TechDocs Addon Framework - -Addons are TechDocs features that are added on top of the base docs-like-code experience. An example would be a feature that showed comments on the page. We plan to add an Addon framework and open source a selection of the Addons that we use internally at Spotify. We encourage the Backstage community to add further Addons. - -For more information about the TechDocs Addon Framework, see the documentation page [here](https://backstage.io/docs/features/techdocs/addons). - -For general information about TechDocs including roadmap, see [here](https://backstage.io/docs/features/techdocs/techdocs-overview). - ### Software Catalog pagination Today adopters with a big catalog (with several thousands of software components) might not have an ideal end-user experience when viewing the `/catalog` page. The issue is related to how the entities are fetched by the frontend. In order to provide a better end-user experience the pagination of the catalog’s entities needs to be enforced. Some experimentation is already completed but in this quarter we plan to continue, and hopefully complete, this relevant enhancement. diff --git a/docs/plugins/customization.md b/docs/plugins/customization.md new file mode 100644 index 0000000000..44ca5147ea --- /dev/null +++ b/docs/plugins/customization.md @@ -0,0 +1,68 @@ +--- +id: customization +title: Customization (Experimental) +description: Documentation on adding a customization logic to the plugin +--- + +## Overview + +The Backstage core logic provides a possibility to make the component customizable in such a way that the application +developer can redefine the labels, icons, elements or even completely replace the component. It's up to each plugin +to decide what can be customized. + +## For a plugin developer + +When you are creating your plugin, you have a possibility to use a metadata field and define there all +customizable elements. For example + +```typescript jsx +const plugin = createPlugin({ + id: 'my-plugin', + __experimentalConfigure( + options?: CatalogInputPluginOptions, + ): CatalogPluginOptions { + const defaultOptions = { + createButtonTitle: 'Create', + }; + return { ...defaultOptions, ...options }; + }, +}); +``` + +And the rendering part of the exposed component can retrieve that metadata as: + +```typescript jsx +export type CatalogPluginOptions = { + createButtonTitle: string; +}; + +export type CatalogInputPluginOptions = { + createButtonTitle: string; +}; + +export const useCatalogPluginOptions = () => + usePluginOptions(); + +export function DefaultMyPluginWelcomePage() { + const { createButtonTitle } = useCatalogPluginOptions(); + + return ( +
+ +
+ ); +} +``` + +## For an application developer using the plugin + +The way to reconfigure the default values provided by the plugin you can do it via reconfigure method, defined on the +plugin. Example: + +```typescript jsx +import { myPlugin } from '@backstage/my-plugin'; + +myPlugin.__experimentalReconfigure({ + createButtonTitle: 'New', +}); +``` diff --git a/docs/releases/v1.4.0-changelog.md b/docs/releases/v1.4.0-changelog.md new file mode 100644 index 0000000000..484939f796 --- /dev/null +++ b/docs/releases/v1.4.0-changelog.md @@ -0,0 +1,2870 @@ +# Release v1.4.0 + +## @backstage/plugin-catalog-node@1.0.0 + +### Major Changes + +- 9a6aba1d85: This package houses stable types from the `@backstage/plugin-catalog-backend` package and is intended for creation of catalog modules. Prefer importing from this package over the `@backstage/plugin-catalog-backend` package. + +### Minor Changes + +- 91c1d12123: Added alpha exports for the new experimental backend system. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.0 + - @backstage/catalog-model@1.1.0 + - @backstage/errors@1.1.0 + +## @backstage/plugin-search@1.0.0 + +### Major Changes + +- 7bd7d336b2: This package has been promoted to 1.0. Read more about what it means in [New release: Backstage Search 1.0 blog](https://backstage.io/blog/2022/07/19/releasing-backstage-search-1.0) + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- 509c4092f0: To allow people to use a global search context in the search modal, the code for the search modal has been changed to only create a local search context if there is no parent context already defined. + + If you want to continue using a local context even if you define a global one, you will have to wrap the modal in a new local context manually: + + ```tsx + + + + ``` + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-search-backend@1.0.0 + +### Major Changes + +- 7bd7d336b2: This package has been promoted to 1.0. Read more about what it means in [New release: Backstage Search 1.0 blog](https://backstage.io/blog/2022/07/19/releasing-backstage-search-1.0) + +### Patch Changes + +- a21cd43467: If error is `MissingIndexError` we return a 400 response with a more clear error message. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-search-backend-node@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/plugin-permission-node@0.6.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-search-backend-module-elasticsearch@1.0.0 + +### Major Changes + +- 7bd7d336b2: This package has been promoted to 1.0. Read more about what it means in [New release: Backstage Search 1.0 blog](https://backstage.io/blog/2022/07/19/releasing-backstage-search-1.0) + +### Minor Changes + +- c5af773757: **BREAKING**: In order to remain interoperable with all currently supported + deployments of Elasticsearch, this package will now conditionally use either + the `@elastic/elasticsearch` or `@opensearch-project/opensearch` client when + communicating with your deployed cluster. + + If you do not rely on types exported from this package, or if you do not make + use of the `createElasticSearchClientOptions` or `newClient` methods on the + `ElasticSearchSearchEngine` class, then upgrading to this version should not + require any further action on your part. Everything will continue to work as it + always has. + + If you _do_ rely on either of the above methods or any underlying types, some + changes may be needed to your custom code. A type guard is now exported by this + package (`isOpenSearchCompatible(options)`), which you may use to help clarify + which client options are compatible with which client constructors. + + If you are using this package with the `search.elasticsearch.provider` set to + `aws`, and you are making use of the `newClient` method in particular, you may + wish to start using the `@opensearch-project/opensearch` client in your custom + code. + +### Patch Changes + +- 71de198828: Updated dependency `@opensearch-project/opensearch` to `^2.0.0`. + +- b0b8213056: Feature: add a new option to set the batch size for elastic search engine, if not given the default batch size is 1000 + + Example usage: + + ```yaml + search: + elasticsearch: + batchSize: 100 + ``` + +- a21cd43467: Throws `MissingIndexError` when no index of type exist. + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.0 + - @backstage/plugin-search-common@1.0.0 + +## @backstage/plugin-search-backend-node@1.0.0 + +### Major Changes + +- 7bd7d336b2: This package has been promoted to 1.0. Read more about what it means in [New release: Backstage Search 1.0 blog](https://backstage.io/blog/2022/07/19/releasing-backstage-search-1.0) + +### Patch Changes + +- a21cd43467: Exports `MissingIndexError` that can be used by the search engines for better error handling when missing index. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-search-common@1.0.0 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-search-common@1.0.0 + +### Major Changes + +- 7bd7d336b2: This package has been promoted to 1.0. Read more about what it means in [New release: Backstage Search 1.0 blog](https://backstage.io/blog/2022/07/19/releasing-backstage-search-1.0) + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.6.3 + +## @backstage/plugin-search-react@1.0.0 + +### Major Changes + +- 7bd7d336b2: This package has been promoted to 1.0. Read more about what it means in [New release: Backstage Search 1.0 blog](https://backstage.io/blog/2022/07/19/releasing-backstage-search-1.0) + +### Patch Changes + +- 60408ca9d4: Fix search pagination to reset page cursor also when a term is cleared. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/backend-app-api@0.1.0 + +### Minor Changes + +- 91c1d12123: Add initial plumbing for creating backends using the experimental backend framework. + + This package is highly **EXPERIMENTAL** and should not be used in production. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.0 + - @backstage/backend-common@0.14.1 + - @backstage/plugin-permission-node@0.6.3 + - @backstage/backend-tasks@0.3.3 + +## @backstage/backend-plugin-api@0.1.0 + +### Minor Changes + +- 91c1d12123: Introduced new package for creating backend plugins using the new alpha backend plugin framework. + This package is still considered **EXPERIMENTAL** and things will change without warning. Do not use this for production. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/backend-tasks@0.3.3 + +## @backstage/catalog-model@1.1.0 + +### Minor Changes + +- 4cc81372f8: Introduced `GroupDefaultParentEntityPolicy` to set a default group entity parent. +- 1380b389dc: Adding an optional type field to entity links to group and categorize links + +### Patch Changes + +- c3cfc83af2: Updated JSDoc to be MDX compatible. +- f9f1de8100: Add shared annotations for Kubernetes clusters +- f1dcc6f3c6: Added type predicates for all entity types, e.g. isUserEntity +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- Updated dependencies + - @backstage/errors@1.1.0 + +## @backstage/cli@0.18.0 + +### Minor Changes + +- 96a82d9791: **BREAKING**: Removed the following deprecated package commands: + + - `app:build` - Use `package build` instead + - `app:serve` - Use `package start` instead + - `backend:build` - Use `package build` instead + - `backend:bundle` - Use `package build` instead + - `backend:dev` - Use `package start` instead + - `plugin:build` - Use `package build` instead + - `plugin:serve` - Use `package start` instead + - `build` - Use `package build` instead + - `lint` - Use `package lint` instead + - `prepack` - Use `package prepack` instead + - `postpack` - Use `package postpack` instead + + In order to replace these you need to have [migrated to using package roles](https://backstage.io/docs/tutorials/package-role-migration). + +### Patch Changes + +- 86640214f0: Upgrade `@rollup/plugin-node-resolve` to `^13.0.6` +- d2256c0384: Fix `webpack-dev-server` deprecations. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- e661242844: Updated dependency `run-script-webpack-plugin` to `^0.1.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- e8ed804d4f: Updated dependency `@spotify/prettier-config` to `^14.0.0`. + Updated dependency `@spotify/eslint-config-base` to `^14.0.0`. + Updated dependency `@spotify/eslint-config-react` to `^14.0.0`. + Updated dependency `@spotify/eslint-config-typescript` to `^14.0.0`. +- e662b573cf: Updated dependency `@octokit/request` to `^6.0.0`. +- f6b6fb7165: The `test` command now ensures that all IO is flushed before exiting when printing `--help`. +- Updated dependencies + - @backstage/config-loader@1.1.3 + - @backstage/release-manifests@0.0.5 + - @backstage/errors@1.1.0 + +## @backstage/core-components@0.10.0 + +### Minor Changes + +- 32204fa794: Add `transformLinkUri` and `transformImageUri` to `MarkdownContent` + +### Patch Changes + +- 3c440ea77e: Change BackstageIconLinkVertical style to use pallette instead of explicit color +- c3cfc83af2: Updated JSDoc to be MDX compatible. +- b4b711bcc2: Fix the EntityLayout header style so that EntityContextMenu button can display in correct shape when user hover on it +- 944af7f2a8: Work around a bug calling `onChange` twice in `mui` for `RoutedTab` so you don't have to press back twice to navigate through tabs +- 7f5e79961d: Fix relative `sub-paths` by concatenating the app's base path with them. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 693990d4fe: Updated dependency `@react-hookz/web` to `^15.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 15201b1032: Updated dependency `rc-progress` to `3.4.0`. +- 7e115d42f9: Support displaying subtitle text in `SidebarSubmenuItem` +- ae746946f7: Improve accessibility for CopyTextButton +- 385389d23c: Updated to remove usage of the `bursts` object in the theme palette +- Updated dependencies + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/errors@1.1.0 + +### Minor Changes + +- 6d61b44466: The `ResponseError.fromResponse` now accepts a more narrow response type, in order to avoid incompatibilities between different fetch implementations. + + The `response` property of `ResponseError` has also been narrowed to a new `ConsumedResponse` type that omits all the properties for consuming the body of the response. This is not considered a breaking change as it was always an error to try to consume the body of the response. + +### Patch Changes + +- c1a8bbf5e5: Inline the type of `ConsumedResponse.headers` and tweaked it to be the intersection of the built-in type and `node-fetch` type. + +## @backstage/plugin-apache-airflow@0.2.0 + +### Minor Changes + +- 01f976ea72: Exposed DagTableComponent as standalone component + added a prop to get only select DAGs instead of the full list + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + +## @backstage/plugin-api-docs-module-protoc-gen-doc@0.1.0 + +### Minor Changes + +- e0328f2107: Added the new `grpcDocsApiWidget` to render `protoc-gen-doc` generated descriptors by the `grpc-docs` package. + +## @backstage/plugin-apollo-explorer@0.1.0 + +### Minor Changes + +- d8fec19542: Apollo Explorer plugin now available! Installation instructions can be found in the plugin README + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-auth-backend@0.15.0 + +### Minor Changes + +- 9d4040777e: **BREAKING**: Removed all directly exported auth provider factories, option types, and sign-in resolvers. For example: `AwsAlbProviderOptions`, `bitbucketUserIdSignInResolver`, `createGithubProvider`. These are all still accessible via the `providers` export. For example, use `providers.github.create()` rather than `createGithubProvider()`, and `providers.bitbucket.resolvers.userIdMatchingUserEntityAnnotation()` rather than `bitbucketUserIdSignInResolver`. + + **BREAKING**: Removed the exported `AuthProviderFactoryOptions` type as well as the deprecated option fields of the `AuthProviderFactory` callback. This includes the `tokenManager`, `tokenIssuer`, `discovery`, and `catalogApi` fields. Existing usage of these should be replaced with the new utilities in the `resolverContext` field. The deprecated `TokenIssuer` type is now also removed, since it is no longer used. + + **BREAKING**: Removed `getEntityClaims`, use `getDefaultOwnershipEntityRefs` instead. + + **DEPRECATION**: Deprecated `AtlassianAuthProvider` as it was unintentionally exported. + +- fe8e025af5: Allowed post method on /refresh path + +### Patch Changes + +- 3cedfd8365: add Cloudflare Access auth provider to auth-backend +- f2cf79d62e: Added an option for the auth backend router to select the algorithm for the JWT token signing keys +- 8e03db907a: Auth provider now also export createAuthProviderIntegration +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- 859346bfbb: Updated dependency `google-auth-library` to `^8.0.0`. +- 3a014730dc: Add new config option for okta auth server and IDP +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-catalog@1.4.0 + +### Minor Changes + +- 97c46f2359: Add `spec.targets` (or `spec.target`) for Location entities at the `CatalogTable`. +- cf288221d1: Add `Location` target(s) to `AboutCard`. +- a274fe38b9: Add hidden title column to catalog and API table to enable filtering by title. + +### Patch Changes + +- dcaf1cb418: Previously, the color of the Entity Context Menu (in the Entity Page Header) was hardcoded as `white`. + + This was an issue for themes that use a header with a white background. By default, the color of the icon is now `theme.page.fontColor`. + + It can now also be overridden in the theme, which is only necessary if the header title, subtitle and three-dots icon need to have different colors. For example: + + ```typescript + export function createThemeOverrides(theme: BackstageTheme): Overrides { + return { + PluginCatalogEntityContextMenu: { + button: { + color: 'blue', + }, + }, + ... + }, + ... + } + ``` + +- f1dcc6f3c6: Use entity type predicates from catalog-model + +- 258057a4b9: Adding ability to customize the "unregister entity" menu item in the entity context menu on the entity page with options 'visible','hidden','disabled'.With this three new options, one can hide the "unregister entity" menu item from the list, disable or keep it enabled. + + The boolean input for "unregister entity" will be deprecated later in favour of the above three options. + +- 385389d23c: Updated to remove usage of the `bursts` object in the theme palette + +- be26d95141: Added new `EntityProcessingStatusPicker` that will filter for entities with orphans and/or errors. + + If you are using the default Catalog page this picker will be added automatically. For those who have customized their Catalog page you'll need to add this manually by doing something like this: + + ```diff + ... + import { + CatalogFilterLayout, + EntityTypePicker, + UserListPicker, + EntityTagPicker + + EntityProcessingStatusPicker, + } from '@backstage/plugin-catalog-react'; + ... + export const CustomCatalogPage = ({ + columns, + actions, + initiallySelectedFilter = 'owned', + }: CatalogPageProps) => { + return ( + ... + + + + + + ... + }; + ``` + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/catalog-client@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + - @backstage/plugin-catalog-common@1.0.4 + +## @backstage/plugin-catalog-backend@1.3.0 + +### Minor Changes + +- 1dd6c22cc8: Added an option to be able to trigger refreshes on entities based on a prestored arbitrary key. + + The UrlReaderProcessor, FileReaderProcessor got updated to store the absolute URL of the catalog file as a refresh key. In the format of `:` + The PlaceholderProcessor got updated to store the resolverValues as refreshKeys for the entities. + + The custom resolvers will need to be updated to pass in a `CatalogProcessorEmit` function as parameter and they should be updated to emit their refresh processingResults. You can see the updated resolvers in the `PlaceholderProcessor.ts` + + ```ts + // yamlPlaceholderResolver + ... + const { content, url } = await readTextLocation(params); + + params.emit(processingResult.refresh(`url:${url}`)); + ... + ``` + +- 91c1d12123: Export experimental `catalogPlugin` for the new backend system. This export is not considered stable and should not be used in production. + +### Patch Changes + +- 1e02fe46d6: Fixed bug where catalog metrics weren't being tracked. + +- 5f6b847c15: Fix Error Code in Register Component DryRun + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. + +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- 679b32172e: Updated dependency `knex` to `^2.0.0`. + +- fa0533e604: CatalogBuilder supports now subscription to processing engine errors. + + ```ts + subscribe(options: { + onProcessingError: (event: { unprocessedEntity: Entity, error: Error }) => Promise | void; + }); + ``` + + If you want to get notified on errors while processing the entities, you call CatalogBuilder.subscribe + to get notifications with the parameters defined as above. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- f1dcc6f3c6: Use entity type predicates from catalog-model + +- 9a6aba1d85: Many symbol declarations have been moved to `@backstage/plugin-catalog-node`. This has no affect on users of this package as they are all re-exported. Modules that build on top of the catalog backend plugin should switch all of their imports to the `@backstage/plugin-catalog-node` package and remove the dependency on `@backstage/plugin-catalog-backend`. + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/plugin-catalog-node@1.0.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/plugin-permission-node@0.6.3 + - @backstage/errors@1.1.0 + - @backstage/plugin-catalog-common@1.0.4 + - @backstage/plugin-scaffolder-common@1.1.2 + +## @backstage/plugin-catalog-backend-module-msgraph@0.4.0 + +### Minor Changes + +- a145672f0f: Align `msgraph` plugin's entity provider config with other providers. **Deprecated** entity processor as well as previous config. + + You will see warning at the log output until you migrate to the new setup. + All deprecated parts will be removed eventually after giving some time to migrate. + + Please find information on how to migrate your current setup to the new one below. + + **Migration Guide:** + + There were two different way on how to use the msgraph plugin: processor or provider. + + Previous registration for the processor: + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addProcessor( + MicrosoftGraphOrgReaderProcessor.fromConfig(env.config, { + logger: env.logger, + // [...] + }), + ); + ``` + + Previous registration when using the provider: + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addEntityProvider( + MicrosoftGraphOrgEntityProvider.fromConfig(env.config, { + id: 'https://graph.microsoft.com/v1.0', + target: 'https://graph.microsoft.com/v1.0', + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + // [...] + }), + ); + ``` + + Previous configuration as used for both: + + ```yaml + # app-config.yaml + catalog: + processors: + microsoftGraphOrg: + providers: + - target: https://graph.microsoft.com/v1.0 + # [...] + ``` + + **Replacement:** + + Please check for the complete documentation of all configuration options (config as well as registration of the provider). + + ```yaml + # app-config.yaml + catalog: + providers: + microsoftGraphOrg: + # In case you used the deprecated configuration with the entity provider + # using the value of `target` will keep the same location key for all + providerId: # some stable ID which will be used as part of the location key for all ingested data + target: https://graph.microsoft.com/v1.0 + # [...] + ``` + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addEntityProvider( + MicrosoftGraphOrgEntityProvider.fromConfig(env.config, { + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + // [...] + }), + ); + ``` + + In case you've used multiple entity providers before + **and** you had different transformers for each of them + you can provide these directly at the one `fromConfig` call + by passing a Record with the provider ID as key. + +- b8ebecd100: Microsoft Graph plugin can supports many more options for authenticating with the Microsoft Graph API. + Previously only ClientId/ClientSecret was supported, but now all the authentication options of `DefaultAzureCredential` from `@azure/identity` are supported. + Including Managed Identity, Client Certificate, Azure CLI and VS Code. + + If `clientId` and `clientSecret` are specified in configuration, the plugin behaves the same way as before. + If these fields are omitted, the plugin uses `DefaultAzureCredential` to automatically determine the best authentication method. + This is particularly useful for local development environments - the default configuration will try to use existing credentials from Visual Studio Code, Azure CLI and Azure PowerShell, without the user needing to configure any credentials in app-config.yaml + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/catalog-model@1.1.0 + - @backstage/backend-tasks@0.3.3 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.0 + +### Minor Changes + +- 67503d159e: Add basic OpenAPI \\$ref support. + + For more information see [here](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend-module-openapi). + +### Patch Changes + +- 4881dc4c84: Updated dependency `openapi-types` to `^12.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + +## @backstage/plugin-code-coverage@0.2.0 + +### Minor Changes + +- d70aaa7622: Cleaned up API exports. + + The `Router` export has been removed; users are expected to use `EntityCodeCoverageContent` instead. + + The `isPluginApplicableToEntity` helper has been deprecated, in favor of the `isCodeCoverageAvailable` helper. + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-code-coverage-backend@0.2.0 + +### Minor Changes + +- d70aaa7622: Cleaned up API exports. + + The `CodeCoverageApi` and `makeRouter` exports have been removed from the backend, since they were not meant to be exported in the first place. + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/errors@1.1.0 + +## @backstage/plugin-cost-insights-common@0.1.0 + +### Minor Changes + +- 81dd5ea989: Introduces a new isomorphic @backstage/plugin-cost-insight-common package to contain shared types across all other cost insights packages and modules. + +## @backstage/plugin-kubernetes@0.7.0 + +### Minor Changes + +- f5c9730639: Add `localKubectlProxy` cluster locator method to make local development simpler to setup. + + Consolidated no-op server side auth decorators. + The following Kubernetes auth decorators are now one class (`ServerSideKubernetesAuthProvider`): + + - `AwsKubernetesAuthProvider` + - `AzureKubernetesAuthProvider` + - `ServiceAccountKubernetesAuthProvider` + +### Patch Changes + +- 3ec294a186: expose detectErrors function publicly +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- eadb3a8d2e: Updated dependency `@kubernetes/client-node` to `^0.17.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-kubernetes-common@0.4.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-kubernetes-backend@0.7.0 + +### Minor Changes + +- f5c9730639: Add `localKubectlProxy` cluster locator method to make local development simpler to setup. + + Consolidated no-op server side auth decorators. + The following Kubernetes auth decorators are now one class (`ServerSideKubernetesAuthProvider`): + + - `AwsKubernetesAuthProvider` + - `AzureKubernetesAuthProvider` + - `ServiceAccountKubernetesAuthProvider` + +- 1454bf98e7: Add new endpoints to Kubernetes backend plugin + + BREAKING: Kubernetes backend plugin now depends on CatalogApi + + ```typescript + // Create new CatalogClient + const catalogApi = new CatalogClient({ discoveryApi: env.discovery }); + const { router } = await KubernetesBuilder.createBuilder({ + logger: env.logger, + config: env.config, + // Inject it into createBuilder params + catalogApi, + }).build(); + ``` + +- 0791af993f: Refactor `KubernetesObjectsProvider` with new methods, `KubernetesServiceLocator` now takes an `Entity` instead of `serviceId` + +### Patch Changes + +- 60e5f9fe68: Fixed the lack of `limitranges` as part of the Default Objects to fetch from the kubernetes api +- 746ec700ea: Add support for Kubernetes clusters in the catalog. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- eadb3a8d2e: Updated dependency `@kubernetes/client-node` to `^0.17.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-kubernetes-common@0.4.0 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-kubernetes-common@0.4.0 + +### Minor Changes + +- 0791af993f: Refactor `KubernetesObjectsProvider` with new methods, `KubernetesServiceLocator` now takes an `Entity` instead of `serviceId` + +### Patch Changes + +- 60e5f9fe68: Fixed the lack of `limitranges` as part of the Default Objects to fetch from the kubernetes api +- eadb3a8d2e: Updated dependency `@kubernetes/client-node` to `^0.17.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.0 + +## @backstage/plugin-newrelic-dashboard@0.2.0 + +### Minor Changes + +- 79ecedded9: Fix bug where the default time window/snapshot duration was supposed to be 30 days, but ended up being 43 weeks + + **BREAKING**: Add a select input to change the time window of the snapshot displayed. This removes the duration prop from the `DashboardSnapshot` component. + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/errors@1.1.0 + +## @backstage/plugin-pagerduty@0.5.0 + +### Minor Changes + +- 8798f8d93f: Introduces a new annotation `pagerduty.com/service-id` that can be used instead of the `pagerduty.com/integration-key` annotation. + _Note: If both annotations are specified on a given Entity, then the `pagerduty.com/integration-key` annotation will be prefered_ + + **BREAKING** The `PagerDutyClient.fromConfig` static method now expects a `FetchApi` compatible object and has been refactored to + accept 2 arguments: config and ClientApiDependencies + The `PagerDutyClient` now relies on a `fetchApi` being available to execute `fetch` requests. + + **BREAKING** A new query method `getServiceByEntity` that is used to query for Services by either the `integrationKey` or `serviceId` + annotation values if they are defined. The `integrationKey` value is preferred currently over `serviceId`. As such, the previous + `getServiceByIntegrationKey` method has been removed. + + **BREAKING** The return values for each Client query method has been changed to return an object instead of raw values. + For example, the `getIncidentsByServiceId` query method now returns an object in the shape of `{ incidents: Incident[] }` + instead of just `Incident[]`. + This same pattern goes for `getChangeEventsByServiceId` and `getOnCallByPolicyId` functions. + + **BREAKING** All public exported types that relate to entities within PagerDuty have been prefixed with `PagerDuty` (e.g. `ServicesResponse` is now `PagerDutyServicesResponse` and `User` is now `PagerDutyUser`) + + In addition, various enhancements/bug fixes were introduced: + + - The `PagerDutyCard` component now wraps error and loading messages with an `InfoCard` to contain errors/messages. This enforces a consistent experience on the EntityPage + - If no service can be found for the provided integration key, a new Error Message Empty State component will be shown instead of an error alert + - Introduces the `fetchApi` to replace standard `window.fetch` + - ensures that Identity Authorization is respected and provided in API requests + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-scaffolder@1.4.0 + +### Minor Changes + +- d8eb82f447: Add `allowedRepos` `ui:option` to `RepoUrlPicker` component, and move `repoName` field to own component +- 9a96199f86: Add support for `allowedOwners` to the `BitbucketRepoPicker` used for the workspace value. + +### Patch Changes + +- 37539e29d8: The template editor now shows the cause of request errors that happen during a dry-run. + +- b557e6c58d: Fixed that adding more than one `allowedOwner` or `allowedRepo` in the template config will now still set the first value as default in the initial form state of `RepoUrlPicker`. + +- 842282ecf9: Bumped `codemirror` dependencies to `v6.0.0`. + +- 11a5ca35f3: Add allowArbitraryValues for to provide input validation. This makes it a better experience of users, as they can now expect the values they enter to correspond to a valid owner. This is set to the default behavior by default. + +- d600cb2ab6: contextMenu prop passed through to from the component + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. + +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. + +- 693990d4fe: Updated dependency `@react-hookz/web` to `^15.0.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 464bb0e6c8: The max content size for dry-run files has been reduced from 256k to 64k. + +- 14146703e5: Add `allowArbitraryValues` to `ui:options` in `OwnedEntityPicker`, similar to `allowArbitraryValues` in `EntityPicker` + +- a7c0b34d70: Swap usage of `MaterialTable` with `Table` from `core-components` + +- 1764296a68: Allow to create Gerrit project using default owner + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + - @backstage/plugin-catalog-common@1.0.4 + - @backstage/plugin-permission-react@0.4.3 + - @backstage/plugin-scaffolder-common@1.1.2 + +## @backstage/plugin-scaffolder-backend@1.4.0 + +### Minor Changes + +- e1a08d872c: Added optional assignee parameter for Gitlab Merge Request action +- dab9bcf2e7: Add `protectEnforceAdmins` as an option to GitHub publish actions +- 4baf8a4ece: Update GitLab Merge Request Action to allow source branch to be deleted +- 91c1d12123: Export experimental `scaffolderCatalogExtension` for the new backend system. This export is not considered stable and should not be used in production. +- d10ccc2ed1: Introduced audit log message when a new scaffolder task is created +- 2db07887cb: Added two new scaffolder actions: `github:repo:create` and `github:repo:push` + +### Patch Changes + +- ff316b86d8: Add `copyWithoutTemplating` to the fetch template action input. `copyWithoutTemplating` also accepts an array of glob patterns. Contents of matched files or directories are copied without being processed, but paths are subject to rendering. + + Deprecate `copyWithoutRender` in favor of `copyWithoutTemplating`. + +- 801d606909: Improve error messaging when passing in malformed auth + +- 089d846962: Fix issues with optional directories and files + +- ea6dcb84a4: Don't resolve symlinks, treat them as binary files and copy them as-is + +- af02f54483: new setUserAsOwner flag for publish:gitlab action + + The field default is `false`. When true it will use the token configured in the gitlab integration for the matching host, to try and set the user logged in via `repoUrlPicker` `requestUserCredentials` OAuth flow as owner of the repository created in GitLab. + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. + +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- 679b32172e: Updated dependency `knex` to `^2.0.0`. + +- 511f49ee43: Updated dependency `octokit` to `^2.0.0`. + +- 735853353b: Updated dependency `@octokit/webhooks` to `^10.0.0`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 945a27fa6a: Add sourcePath option to publish:gerrit action + +- 1764296a68: Allow to create Gerrit project using default owner + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.0 + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-catalog-node@1.0.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/errors@1.1.0 + - @backstage/plugin-scaffolder-common@1.1.2 + +## @backstage/plugin-sentry@0.4.0 + +### Minor Changes + +- 1b7c691a3b: Added the possibility to specify organization per component, now the annotation `sentry.io/project-slug` can have the format of `[organization]/[project-slug]` or just `[project-slug]`. + + **BREAKING**: The method `fetchIssue` changed the signature: + + ```diff + export interface SentryApi { + fetchIssues( + - project: string, + - statsFor: string, + - query?: string, + + entity: Entity, + + options: { + + statsFor: string; + + query?: string; + + }, + ): Promise; + } + ``` + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-tech-insights-backend@0.5.0 + +### Minor Changes + +- 818fa28d71: Allow FactRetrieverRegistry to be injected into buildTechInsightsContext so that we can override default registry implementation. +- 46cfda58aa: **BREAKING**: Update FactRetrieverRegistry interface to be async so that db backed implementations can be passed through to the FactRetrieverEngine. + + If you have existing custom `FactRetrieverRegistry` implementations, you'll need to remove the `retrievers` member and make all the methods async. + +### Patch Changes + +- 2ef58ab539: TechInsightsBackend: Added missing 'scheduler' to code examples +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- bcc122c46d: The `FactRetriever` model has been extended by adding optional title and description fields, allowing you to display them in the UI. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/catalog-client@1.0.4 + - @backstage/backend-tasks@0.3.3 + - @backstage/plugin-tech-insights-common@0.2.5 + - @backstage/plugin-tech-insights-node@0.3.2 + - @backstage/errors@1.1.0 + +## @backstage/plugin-techdocs@1.3.0 + +### Minor Changes + +- ebf3eb1641: Use the same initial filter `owned` for the `TechDocsIndexPage` as for the `CatalogPage`. + + If you prefer to keep the previous behavior, you can change the default for the initial filter + to `all` (or `starred` if you rather prefer that). + + + + In general, with this change you will be able to set props at `TechDocsIndexPage`. + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 3cbebf710e: Reorder browser tab title in Techdocs pages to have the site name first. + +- 726577958f: Remove the 60% factor from the font size calculation of headers to use the exact size defined in BackstageTheme. + +- 7739141ab2: Fix: When docs are shown in an entity page under the docs tab the sidebars start overlapping with the header and tabs in the page when you scroll the documentation content. + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-techdocs-backend@1.2.0 + +### Minor Changes + +- 860765ff45: Added local publishing target directory `config`: `techdocs.publisher.local.publishDirectory` + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- 726577958f: Add sample headings on the documented component homepage. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.2.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/errors@1.1.0 + - @backstage/plugin-catalog-common@1.0.4 + +## @backstage/plugin-techdocs-node@1.2.0 + +### Minor Changes + +- 860765ff45: Added local publishing target directory `config`: `techdocs.publisher.local.publishDirectory` + +### Patch Changes + +- a5d73da942: Fix the flag parsing for `legacyCopyReadmeMdToIndexMd` in `techdocs-cli generate` command, and decouple it's logic from the `techdocs-ref` flag. + +- d505b7b37d: Fixed issue with git feedback buttons not appearing automatically in docs pages. This was done by appending `repo_url` to the helper function `getRepoUrlFromLocationAnnotation`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/integration@1.2.2 + - @backstage/errors@1.1.0 + +## @backstage/plugin-vault-backend@0.2.0 + +### Minor Changes + +- 5ebf2c7023: Throw exceptions instead of swallow them, remove some exported types from the `api-report`, small changes in the API responses & expose the vault `baseUrl` to the frontend as well + +### Patch Changes + +- 7ee4abdcc9: Added a path notion in addition to secret name to allow to differentiate secrets in sub-paths +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/backend-test-utils@0.1.26 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + +## @backstage/app-defaults@1.0.4 + +### Patch Changes + +- 881fc75a75: Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/plugin-permission-react@0.4.3 + +## @backstage/backend-common@0.14.1 + +### Patch Changes + +- b1edb5cfd9: Fix parsing of S3 URLs for the default region. + +- c3cfc83af2: Updated JSDoc to be MDX compatible. + +- e57180e45e: Added some more information to the error messages for `isomorphic-git` errors + +- 1f75dfac29: Fix edge case bug when gitlab relativePath is repeated in the target URL. + +- 90c87f28e8: Moving from Bitbucket Server endpoint from to , to have the last commit in function of different branch, and not only the list of default branch + +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 + +- 0fc57887e8: Improve plural handling in logging output for secrets + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- 679b32172e: Updated dependency `knex` to `^2.0.0`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 954a94f52f: Support self-hosted gitlab installations with relative URL. + +- Updated dependencies + - @backstage/config-loader@1.1.3 + - @backstage/integration@1.2.2 + - @backstage/errors@1.1.0 + +## @backstage/backend-tasks@0.3.3 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/errors@1.1.0 + +## @backstage/backend-test-utils@0.1.26 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/cli@0.18.0 + +## @backstage/catalog-client@1.0.4 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.0 + - @backstage/errors@1.1.0 + +## @backstage/config-loader@1.1.3 + +### Patch Changes + +- bcada7cd9f: From now on the `$file` placeholder will trim the whitespaces and newline characters from the end of the file it reads. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- a3acec8819: Updated dependency `typescript-json-schema` to `^0.54.0`. +- Updated dependencies + - @backstage/errors@1.1.0 + +## @backstage/core-app-api@1.0.4 + +### Patch Changes + +- 881fc75a75: Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. +- 8fe2357101: The `signOut` method of the `IdentityApi` will now navigate the user back to the base URL of the app as indicated by the `app.baseUrl` config. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.4 + +## @backstage/core-plugin-api@1.0.4 + +### Patch Changes + +- 881fc75a75: Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 2990fff4e5: Enabled the `@backstage/core-plugin-api/alpha` entry point. + +## @backstage/create-app@0.4.29 + +### Patch Changes + +- f281ad17c0: Adds the ability to define the Backstage app name using a `BACKSTAGE_APP_NAME` + environment variable when running `create-app`. +- c92deffe39: Bumped create-app version. +- 0e967f188b: Bumped create-app version. +- bc87604c26: Added an explicit `node-gyp` dependency to the root `package.json`. This is to work around a bug in older versions of `node-gyp` that causes Python execution to fail on macOS. + + You can add this workaround to your existing project by adding `node-gyp` as a `devDependency` in your root `package.json` file: + + ```diff + "devDependencies": { + + "node-gyp": "^9.0.0" + }, + ``` + +## @backstage/dev-utils@1.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/app-defaults@1.0.4 + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/test-utils@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/integration@1.2.2 + +### Patch Changes + +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- 1f29047bad: Updated dependency `@octokit/auth-app` to `^4.0.0`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 8829e175f2: Allow frontend visibility for `integrations` itself. + +- 954a94f52f: Support self-hosted gitlab installations with relative URL. + +- 4df3390795: Avoid double encoding of the file path in `getBitbucketServerDownloadUrl` + +- Updated dependencies + - @backstage/errors@1.1.0 + +## @backstage/integration-react@1.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/theme@0.2.16 + +## @backstage/release-manifests@0.0.5 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +## @techdocs/cli@1.1.3 + +### Patch Changes + +- a5d73da942: Fix the flag parsing for `legacyCopyReadmeMdToIndexMd` in `techdocs-cli generate` command, and decouple it's logic from the `techdocs-ref` flag. +- 14ce0d9347: Fixed a bug that prevented docker images from being pulled by default when generating TechDocs. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.2.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + +## @backstage/test-utils@1.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/theme@0.2.16 + - @backstage/plugin-permission-react@0.4.3 + +## @backstage/theme@0.2.16 + +### Patch Changes + +- ff4f56eb49: **DEPRECATED**: The `bursts` object from `BackstagePaletteAdditions` has been depreciated and will be removed in a future release + + The `genPageTheme` function now includes an optional options object with an optional `fontColor` which defaults to white if not provided. + +- 4c09c09102: Adds optional `htmlFontSize` property and also sets typography design tokens for h5 and h6 in base theme. + +## @backstage/plugin-adr@0.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- 511f49ee43: Updated dependency `octokit` to `^2.0.0`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 7d47e7e512: Track discover event and result rank for `AdrSearchResultListItem` + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/plugin-adr-common@0.1.2 + +## @backstage/plugin-adr-backend@0.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/errors@1.1.0 + - @backstage/plugin-adr-common@0.1.2 + +## @backstage/plugin-adr-common@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/integration@1.2.2 + +## @backstage/plugin-airbrake@0.3.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/test-utils@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/dev-utils@1.0.4 + +## @backstage/plugin-airbrake-backend@0.2.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + +## @backstage/plugin-allure@0.1.23 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-analytics-module-ga@0.1.18 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-api-docs@0.8.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- b76eea25ed: Updated dependency `@asyncapi/react-component` to `1.0.0-next.39`. +- a274fe38b9: Add hidden title column to catalog and API table to enable filtering by title. +- 9432a05cf3: Set font colors correctly for descriptions containing HTML +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-catalog@1.4.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-app-backend@0.3.34 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/config-loader@1.1.3 + +## @backstage/plugin-auth-node@0.2.3 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/errors@1.1.0 + +## @backstage/plugin-azure-devops@0.1.23 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- e049e41048: Exporting azureDevOpsApiRef, AzureGitTagsIcon, and all hooks for the benefit of other plugins. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + - @backstage/plugin-azure-devops-common@0.2.4 + +## @backstage/plugin-azure-devops-backend@0.3.13 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- 13a232ec22: Added comments to example to help avoid confusion as to where lines need to be added + +- e67c4b7d5a: Adding getProjects endpoint to list out all projects associated with the Azure DevOps organization. + + It can be accessed by using this endpoint `{backendUrl}/api/azure-devops/projects` + +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-azure-devops-common@0.2.4 + +## @backstage/plugin-azure-devops-common@0.2.4 + +### Patch Changes + +- e67c4b7d5a: Adding getProjects endpoint to list out all projects associated with the Azure DevOps organization. + + It can be accessed by using this endpoint `{backendUrl}/api/azure-devops/projects` + +## @backstage/plugin-badges@0.2.31 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-badges-backend@0.1.28 + +### Patch Changes + +- 58fd5ee9d5: Add missing installation instructions +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/catalog-client@1.0.4 + - @backstage/errors@1.1.0 + +## @backstage/plugin-bazaar@0.1.22 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 77abf50acf: Fixed api warnings +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-catalog@1.4.0 + - @backstage/cli@0.18.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + +## @backstage/plugin-bazaar-backend@0.1.18 + +### Patch Changes + +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- 77abf50acf: Fixed api warnings +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/backend-test-utils@0.1.26 + +## @backstage/plugin-bitbucket-cloud-common@0.1.1 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/integration@1.2.2 + +## @backstage/plugin-bitrise@0.1.34 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-catalog-backend-module-aws@0.1.7 + +### Patch Changes + +- f9f1de8100: Add processor for ingesting EKS clusters into the catalog +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-catalog-backend-module-azure@0.1.5 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.1 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/plugin-bitbucket-cloud-common@0.1.1 + - @backstage/errors@1.1.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.1 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/integration@1.2.2 + - @backstage/plugin-bitbucket-cloud-common@0.1.1 + - @backstage/backend-tasks@0.3.3 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-catalog-backend-module-github@0.1.5 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 0f25116d28: Updated dependency `@octokit/graphql` to `^5.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.1.5 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- 49ff472c0b: Add the possibility in the `GitlabDiscoveryEntityProvider` to scan the whole project instead of concrete groups. For that, use a configuration like this one, where the group parameter is omitted (not mandatory anymore): + + ```yaml + catalog: + providers: + gitlab: + yourProviderId: + host: gitlab-host # Identifies one of the hosts set up in the integrations + branch: main # Optional. Uses `master` as default + entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml` + ``` + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.1 + +### Patch Changes + +- ddfd566606: Fix mapping between users and groups for FreeIPA when using the LdapOrgProcessor +- fbfbff6bf7: Add possibility to resolve relations by RDN, in addition to UUID and DN +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/catalog-model@1.1.0 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-catalog-common@1.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-common@1.0.0 + - @backstage/plugin-permission-common@0.6.3 + +## @backstage/plugin-catalog-graph@0.2.19 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-catalog-graphql@0.3.11 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.0 + +## @backstage/plugin-catalog-import@0.8.10 + +### Patch Changes + +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 272106fdad: Support use without `integrations` or only integrations without frontend visible properties (e.g., `bitbucketCloud`) being configured by checking `integrations.github` directly without attempting to load `integrations`. + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/errors@1.1.0 + +## @backstage/plugin-catalog-react@1.1.2 + +### Patch Changes + +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. + +- be26d95141: Added new `EntityProcessingStatusPicker` that will filter for entities with orphans and/or errors. + + If you are using the default Catalog page this picker will be added automatically. For those who have customized their Catalog page you'll need to add this manually by doing something like this: + + ```diff + ... + import { + CatalogFilterLayout, + EntityTypePicker, + UserListPicker, + EntityTagPicker + + EntityProcessingStatusPicker, + } from '@backstage/plugin-catalog-react'; + ... + export const CustomCatalogPage = ({ + columns, + actions, + initiallySelectedFilter = 'owned', + }: CatalogPageProps) => { + return ( + ... + + + + + + ... + }; + ``` + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + - @backstage/plugin-catalog-common@1.0.4 + - @backstage/plugin-permission-react@0.4.3 + +## @backstage/plugin-cicd-statistics@0.1.9 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.3 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-cicd-statistics@0.1.9 + +## @backstage/plugin-circleci@0.3.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-cloudbuild@0.3.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-code-climate@0.1.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-codescene@0.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 15201b1032: Updated dependency `rc-progress` to `3.4.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-config-schema@0.1.30 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-cost-insights@0.11.29 + +### Patch Changes + +- 3e032a5de2: Move cost-insights data specific API types (non react) into an @backstage/plugin-cost-insights-common + isomorphic package. This allows these types to be shared in any backend packages or other cost-insight + modules. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-cost-insights-common@0.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-dynatrace@0.1.1 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-explore@0.3.38 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-explore-react@0.0.19 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-explore-react@0.0.19 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.4 + +## @backstage/plugin-firehydrant@0.1.24 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-fossa@0.2.39 + +### Patch Changes + +- 322d1ceeba: Allow configuration of base URL for Fossa links +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-gcalendar@0.3.3 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-gcp-projects@0.3.26 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 693990d4fe: Updated dependency `@react-hookz/web` to `^15.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-git-release-manager@0.3.20 + +### Patch Changes + +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-github-actions@0.5.7 + +### Patch Changes + +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 217f919f0a: Minor cleanup of the API surface. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-github-deployments@0.1.38 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 0f25116d28: Updated dependency `@octokit/graphql` to `^5.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-github-pull-requests-board@0.1.1 + +### Patch Changes + +- c6690d9d24: Fix bug on fetching teams repositories where were being filtered by type service unnecessarily +- 04e1504e85: Support namespaced teams and fetch all kinds +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-gitops-profiles@0.3.25 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-gocd@0.1.13 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-graphiql@0.2.39 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-graphql-backend@0.1.24 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-catalog-graphql@0.3.11 + +## @backstage/plugin-home@0.4.23 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- a46e317a75: Added support for customizing the time format used in the `HeaderWorldClock` component + + Here's an example of how this can be used in the `HomePage.tsx` found in `\packages\app\src\components\home` to change the clock to be in the 24hr time format: + + ```diff + +const timeFormat: Intl.DateTimeFormatOptions = { + + hour: '2-digit', + + minute: '2-digit', + + hour12: false, + +}; + + export const homePage = ( + +
} pageTitleOverride="Home"> + + +
+ + + + + + ``` + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-stack-overflow@0.1.3 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-ilert@0.1.33 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-jenkins@0.7.6 + +### Patch Changes + +- 8747824221: feature: added support for multiple branches to the `JenkinsApi` +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + - @backstage/plugin-jenkins-common@0.1.6 + +## @backstage/plugin-jenkins-backend@0.1.24 + +### Patch Changes + +- 8747824221: feature: added support for multiple branches to the `JenkinsApi` +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/errors@1.1.0 + - @backstage/plugin-jenkins-common@0.1.6 + +## @backstage/plugin-jenkins-common@0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.6.3 + - @backstage/plugin-catalog-common@1.0.4 + +## @backstage/plugin-kafka@0.3.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-kafka-backend@0.2.27 + +### Patch Changes + +- 8751667541: Updated dependency `kafkajs` to `^2.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/errors@1.1.0 + +## @backstage/plugin-lighthouse@0.3.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-newrelic@0.3.25 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-org@0.5.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 1e984b11fc: Render namespaces for teams with subtitles in `MyGroupsSidebarItem` +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-periskop@0.1.5 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-periskop-backend@0.1.5 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + +## @backstage/plugin-permission-backend@0.5.9 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/plugin-permission-node@0.6.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-permission-common@0.6.3 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/errors@1.1.0 + +## @backstage/plugin-permission-node@0.6.3 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/errors@1.1.0 + +## @backstage/plugin-permission-react@0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-permission-common@0.6.3 + +## @backstage/plugin-proxy-backend@0.2.28 + +### Patch Changes + +- a4fa1ce090: The proxy-backend now automatically reloads configuration when app-config.yaml is updated. +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + +## @backstage/plugin-rollbar@0.4.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-rollbar-backend@0.1.31 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.9 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-scaffolder-backend@1.4.0 + - @backstage/integration@1.2.2 + - @backstage/errors@1.1.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-scaffolder-backend@1.4.0 + - @backstage/integration@1.2.2 + - @backstage/errors@1.1.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.4.0 + +## @backstage/plugin-scaffolder-common@1.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.0 + +## @backstage/plugin-search-backend-module-pg@0.3.5 + +### Patch Changes + +- 423e3d8e95: **DEPRECATED**: `PgSearchEngine` static `from` has been deprecated and will be removed in a future release. Use static `fromConfig` method to instantiate. + + Added support for highlighting matched terms in search result data + +- 679b32172e: Updated dependency `knex` to `^2.0.0`. + +- 886e99b8e7: Now imports `SearchEngine` interface from `@backstage/plugin-search-common` instead of `@backstage/plugin-search-backend-node` + +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-search-backend-node@1.0.0 + - @backstage/plugin-search-common@1.0.0 + +## @backstage/plugin-shortcuts@0.2.8 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-sonarqube@0.3.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 15201b1032: Updated dependency `rc-progress` to `3.4.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-splunk-on-call@0.3.31 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-stack-overflow@0.1.3 + +### Patch Changes + +- 12ae3eed2f: - Publicly exports `StackOverflowIcon`. + - `HomePageStackOverflowQuestions` accepts optional icon property. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 52b4f796e3: app-config is now picked up properly. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-home@0.4.23 + - @backstage/theme@0.2.16 + +## @backstage/plugin-stack-overflow-backend@0.1.3 + +### Patch Changes + +- 52b4f796e3: app-config is now picked up properly. +- Updated dependencies + - @backstage/plugin-search-common@1.0.0 + +## @backstage/plugin-tech-insights@0.2.3 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-tech-insights-common@0.2.5 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.18 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-tech-insights-common@0.2.5 + - @backstage/plugin-tech-insights-node@0.3.2 + - @backstage/errors@1.1.0 + +## @backstage/plugin-tech-insights-common@0.2.5 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. + +## @backstage/plugin-tech-insights-node@0.3.2 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- bcc122c46d: The `FactRetriever` model has been extended by adding optional title and description fields, allowing you to display them in the UI. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-tech-insights-common@0.2.5 + +## @backstage/plugin-tech-radar@0.5.14 + +### Patch Changes + +- b8f608f1ec: Update tech-radar documentation on how to use an external json data source with dates. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-catalog@1.4.0 + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/test-utils@1.1.2 + - @backstage/plugin-techdocs@1.3.0 + - @backstage/theme@0.2.16 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. + +- 693990d4fe: Updated dependency `@react-hookz/web` to `^15.0.0`. + +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/integration-react@1.1.2 + - @backstage/theme@0.2.16 + +## @backstage/plugin-techdocs-react@1.0.2 + +### Patch Changes + +- c3cfc83af2: Updated JSDoc to be MDX compatible. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + +## @backstage/plugin-todo@0.2.9 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-todo-backend@0.1.31 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/errors@1.1.0 + +## @backstage/plugin-user-settings@0.4.6 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @backstage/plugin-vault@0.1.1 + +### Patch Changes + +- 7ee4abdcc9: Added a path notion in addition to secret name to allow to differentiate secrets in sub-paths +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 5ebf2c7023: Export missing parameters and added them to the api-report. Also adapted the API to the expected response from the backend +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## @backstage/plugin-xcmetrics@0.2.27 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + +## example-app@0.2.73 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-cost-insights@0.11.29 + - @backstage/plugin-code-coverage@0.2.0 + - @backstage/plugin-scaffolder@1.4.0 + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/plugin-search@1.0.0 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/plugin-kubernetes@0.7.0 + - @backstage/plugin-tech-radar@0.5.14 + - @backstage/plugin-catalog@1.4.0 + - @backstage/plugin-newrelic-dashboard@0.2.0 + - @backstage/cli@0.18.0 + - @backstage/plugin-apache-airflow@0.2.0 + - @backstage/app-defaults@1.0.4 + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-jenkins@0.7.6 + - @backstage/plugin-stack-overflow@0.1.3 + - @backstage/plugin-catalog-import@0.8.10 + - @backstage/plugin-github-actions@0.5.7 + - @backstage/plugin-sentry@0.4.0 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-airbrake@0.3.7 + - @backstage/plugin-api-docs@0.8.7 + - @backstage/plugin-azure-devops@0.1.23 + - @backstage/plugin-badges@0.2.31 + - @backstage/plugin-circleci@0.3.7 + - @backstage/plugin-cloudbuild@0.3.7 + - @backstage/plugin-dynatrace@0.1.1 + - @backstage/plugin-explore@0.3.38 + - @backstage/plugin-gcalendar@0.3.3 + - @backstage/plugin-gcp-projects@0.3.26 + - @backstage/plugin-gocd@0.1.13 + - @backstage/plugin-graphiql@0.2.39 + - @backstage/plugin-home@0.4.23 + - @backstage/plugin-kafka@0.3.7 + - @backstage/plugin-lighthouse@0.3.7 + - @backstage/plugin-newrelic@0.3.25 + - @backstage/plugin-org@0.5.7 + - @backstage/plugin-pagerduty@0.5.0 + - @backstage/plugin-rollbar@0.4.7 + - @backstage/plugin-shortcuts@0.2.8 + - @backstage/plugin-tech-insights@0.2.3 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.2 + - @backstage/plugin-techdocs@1.3.0 + - @backstage/plugin-todo@0.2.9 + - @backstage/plugin-user-settings@0.4.6 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.4 + - @backstage/plugin-catalog-graph@0.2.19 + - @backstage/plugin-permission-react@0.4.3 + +## example-backend@0.2.73 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-code-coverage-backend@0.2.0 + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/plugin-tech-insights-backend@0.5.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-kubernetes-backend@0.7.0 + - @backstage/plugin-search-backend@1.0.0 + - @backstage/plugin-search-backend-node@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.0 + - @backstage/plugin-scaffolder-backend@1.4.0 + - @backstage/plugin-auth-backend@0.15.0 + - @backstage/plugin-jenkins-backend@0.1.24 + - @backstage/plugin-proxy-backend@0.2.28 + - @backstage/plugin-search-backend-module-pg@0.3.5 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-app-backend@0.3.34 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/plugin-azure-devops-backend@0.3.13 + - @backstage/plugin-graphql-backend@0.1.24 + - @backstage/plugin-permission-backend@0.5.9 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/plugin-permission-node@0.6.3 + - @backstage/plugin-rollbar-backend@0.1.31 + - @backstage/plugin-techdocs-backend@1.2.0 + - @backstage/plugin-todo-backend@0.1.31 + - @backstage/backend-tasks@0.3.3 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.18 + - @backstage/plugin-tech-insights-node@0.3.2 + - @backstage/plugin-kafka-backend@0.2.27 + - @backstage/plugin-badges-backend@0.1.28 + - example-app@0.2.73 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.2 + +## example-backend-next@0.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/plugin-scaffolder-backend@1.4.0 + - @backstage/backend-app-api@0.1.0 + +## techdocs-cli-embedded-app@0.2.72 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/plugin-catalog@1.4.0 + - @backstage/cli@0.18.0 + - @backstage/app-defaults@1.0.4 + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/test-utils@1.1.2 + - @backstage/plugin-techdocs@1.3.0 + - @backstage/theme@0.2.16 + +## @internal/plugin-todo-list@1.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + +## @internal/plugin-todo-list-backend@1.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/errors@1.1.0 + +## @internal/plugin-todo-list-common@1.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.6.3 diff --git a/docs/releases/v1.4.0.md b/docs/releases/v1.4.0.md new file mode 100644 index 0000000000..20b1739f4a --- /dev/null +++ b/docs/releases/v1.4.0.md @@ -0,0 +1,70 @@ +--- +id: v1.4.0 +title: v1.4.0 +description: Backstage Release v1.4.0 +--- + +These are the release notes for the v1.4.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### Search is V1! + +Backstage Search is now promoted to v1.0 with a stable Search API for plugin developers to add search to their plugins, and app integrators to expose that to their users. + +No additional features are released as part of the major release as the maintainers of the search packages focused on the following for this release: + +- Bug fixes and clean up of deprecations. +- Improved error handling for missing indices. +- Separation of AWS Elastic and Open Elastic support. +- Refactor the packages by moving reusable components from `@backstage/plugin-search` to `@backstage/plugin-search-react`. +- Improved documentation including tutorials for how to [Integrate Search into a plugin](https://backstage.io/docs/plugins/integrating-search-into-plugins). + +With moving to v1.0 we also recommend using Elasticsearch for production usage. Moving forward, the search maintainers will prioritize the Elasticsearch engine while we’ll rely on the community to maintain the Postgres engine. + +### Experimental Backend System Evolution + +This release adds the new `@backstage/backend-app-api` and `@backstage/backend-plugin-api` packages, both part of the [evolution of the backend system](https://github.com/backstage/backstage/issues/11611). These packages are highly experimental and we do not recommend using them for any purpose, yet. + +### `@backstage/cli` Deprecation Removals + +The `@backstage/cli` had a large number of deprecated commands removed, for example, `app:build` is now gone and should be replaced with `package build`. For a full list of commands that were removed, see the [changelog](https://github.com/backstage/backstage/blob/master/packages/cli/CHANGELOG.md#0180). + +### `@backstage/plugin-auth-backend` Deprecation Removals + +Many deprecated symbols have now been removed from `@backstage/plugin-auth-backend`, most notably the provider factories such as `createGithubProvider` have been removed, which should be replaced with `providers.github.create`. See the [changelog](https://github.com/backstage/backstage/blob/master/plugins/auth-backend/CHANGELOG.md#0150) for more details. + +### New module: `@backstage/plugin-api-docs-module-protoc-gen-doc` + +This is a new module for `@backstage/plugin-api-docs` that exports a widget implementation for rendering gRPC docs generated by `protoc-gen-doc`. Contributed by [@kissmikijr](https://github.com/kissmikijr) [#11923](https://github.com/backstage/backstage/pull/11923). + +### New module: `@backstage/plugin-catalog-backend-module-openapi` + +This is a new module for `@backstage/plugin-catalog-backend` that exports a catalog processor which de-references `$ref` fields in OpenAPI definitions. Contributed by [@mfrinnstrom](https://github.com/mfrinnstrom) [#11645](https://github.com/backstage/backstage/pull/11645). + +### New plugin: `@backstage/plugin-apollo-explorer` + +A plugin to embed the [Apollo Explorer](https://github.com/apollographql/embeddable-explorer/tree/main/packages/explorer) inside your Backstage instance to run queries against GraphQL endpoints. Contributed by [@unredundant](https://github.com/unredundant) [#12600](https://github.com/backstage/backstage/pull/12600). + +## Security Fixes + +`@backstage/plugin-scaffolder-backend`, please upgrade to the latest version if you are using this module. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.4.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://mailchi.mp/spotify/backstage-community) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/releases/v1.5.0-changelog.md b/docs/releases/v1.5.0-changelog.md new file mode 100644 index 0000000000..6e4d251ef7 --- /dev/null +++ b/docs/releases/v1.5.0-changelog.md @@ -0,0 +1,1725 @@ +# Release v1.5.0 + +## @backstage/backend-app-api@0.2.0 + +### Minor Changes + +- 5df230d48c: Introduced a new `backend-defaults` package carrying `createBackend` which was previously exported from `backend-app-api`. + The `backend-app-api` package now exports the `createSpecializedBacked` that does not add any service factories by default. + +### Patch Changes + +- 0599732ec0: Refactored experimental backend system with new type names. +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-plugin-api@0.1.1 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-permission-node@0.6.4 + +## @backstage/backend-common@0.15.0 + +### Minor Changes + +- 12e9b54f0e: Added back support for when no branch is provided to the `UrlReader` for Bitbucket Server +- 30012e7d8c: - Added `force` and `remoteRef` option to `push` method in `git` actions + - Added `addRemote` and `deleteRemote` methods to `git` actions + +### Patch Changes + +- fc8a5f797b: Improve `scm/git` wrapper around `isomorphic-git` library : + + - Add `checkout` function, + - Add optional `remoteRef` parameter in the `push` function. + +- 5e4dc173f7: Added a second validation to the `dir()` method of ZIP archive responses returned from `readTree()` that ensures that extracted files do not fall outside the target directory. + +- 1732a18a7a: Exported `redactLogLine` function to be able to use it in custom loggers and renamed it to `redactWinstonLogLine`. + +- 3b7930b3e5: Add support for Bearer Authorization header / token-based auth at Git commands. + +- cfa078e255: The `ZipArchiveResponse` now correctly handles corrupt ZIP archives. + + Before this change, certain corrupt ZIP archives either cause the inflater to throw (as expected), or will hang the parser indefinitely. + + By switching out the `zip` parsing library, we now write to a temporary directory, and load from disk which should ensure that the parsing of the `.zip` files are done correctly because `streaming` of `zip` paths is technically impossible without being able to parse the headers at the end of the file. + +- 770d3f92c4: The config prop `ensureExists` now applies to schema creation when `pluginDivisionMode` is set to `schema`. This means schemas will no longer accidentally be automatically created when `ensureExists` is set to `false`. + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. + +- Updated dependencies + - @backstage/integration@1.3.0 + +## @backstage/backend-defaults@0.1.0 + +### Minor Changes + +- 5df230d48c: Introduced a new `backend-defaults` package carrying `createBackend` which was previously exported from `backend-app-api`. + The `backend-app-api` package now exports the `createSpecializedBacked` that does not add any service factories by default. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.2.0 + - @backstage/backend-plugin-api@0.1.1 + +## @backstage/core-components@0.11.0 + +### Minor Changes + +- d0eefc499a: Made the `to` prop of `Button` and `Link` more strict, only supporting plain strings. It used to be the case that this prop was unexpectedly too liberal, making it look like we supported the complex `react-router-dom` object form of the parameter as well, which led to unexpected results at runtime. + +### Patch Changes + +- a22af3edc8: Adding a `className` prop to the `MarkdownContent` component +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + +## @backstage/integration@1.3.0 + +### Minor Changes + +- 593dea6710: Add support for Basic Auth for Bitbucket Server. +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer + +### Patch Changes + +- 163243a4d1: Handle incorrect return type from Octokit paginate plugin to resolve reading URLs from GitHub +- c4b460a47d: Avoid double encoding of the file path in `getBitbucketDownloadUrl` +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- 1f27d83933: Fixed bug in getGitLabFileFetchUrl where a target whose path did not contain the + `/-/` scope would result in a fetch URL that did not support + private-token-based authentication. + +## @techdocs/cli@1.2.0 + +### Minor Changes + +- 855952db53: Added CLI option `--docker-option` to allow passing additional options to the `docker run` command executed my `serve` and `serve:mkdocs`. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-techdocs-node@1.3.0 + +## @backstage/plugin-adr@0.2.0 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-adr-common@0.2.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## @backstage/plugin-adr-backend@0.2.0 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-adr-common@0.2.0 + - @backstage/integration@1.3.0 + +## @backstage/plugin-adr-common@0.2.0 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + +## @backstage/plugin-catalog@1.5.0 + +### Minor Changes + +- 80da5162c7: Plugin catalog has been modified to use an experimental feature where you can customize the title of the create button. + + You can modify it by doing: + + ```typescript jsx + import { catalogPlugin } from '@backstage/plugin-catalog'; + + catalogPlugin.__experimentalReconfigure({ + createButtonTitle: 'New', + }); + ``` + +- fe94398418: Allow changing the subtitle of the `CatalogTable` component + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-catalog-common@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.0 + +### Minor Changes + +- f7607f9d85: Add new plugin catalog-backend-module-bitbucket-server which adds the `BitbucketServerEntityProvider`. + + The entity provider is meant as a replacement for the `BitbucketDiscoveryProcessor` to be used with Bitbucket Server (Bitbucket Cloud already has a replacement). + + **Before:** + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addProcessor( + BitbucketDiscoveryProcessor.fromConfig(env.config, { logger: env.logger }), + ); + ``` + + ```yaml + # app-config.yaml + catalog: + locations: + - type: bitbucket-discovery + target: 'https://bitbucket.mycompany.com/projects/*/repos/*/catalog-info.yaml + ``` + + **After:** + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addEntityProvider( + BitbucketServerEntityProvider.fromConfig(env.config, { + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + }), + ); + ``` + + ```yaml + # app-config.yaml + catalog: + providers: + bitbucketServer: + yourProviderId: # identifies your ingested dataset + catalogPath: /catalog-info.yaml # default value + filters: # optional + projectKey: '.*' # optional; RegExp + repoSlug: '.*' # optional; RegExp + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## @backstage/plugin-github-issues@0.1.0 + +### Minor Changes + +- ffd5e47fb5: New plugin for displaying GitHub Issues added + +### Patch Changes + +- 347ea327c2: Moved communication with GitHub graphql API to the dedicated plugin API. + Fixes issue when no GitHub Issues are rendered when partial failure is returned from GitHub API. +- b522f49403: Updated dependency `@spotify/prettier-config` to `^14.0.0`. +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-scaffolder@1.5.0 + +### Minor Changes + +- c4b452e16a: Starting the implementation of the Wizard page for the `next` scaffolder plugin + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-catalog-common@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-permission-react@0.4.4 + +## @backstage/plugin-scaffolder-backend@1.5.0 + +### Minor Changes + +- c4b452e16a: Starting the implementation of the Wizard page for the `next` scaffolder plugin +- 593dea6710: Add support for Basic Auth for Bitbucket Server. +- 3b7930b3e5: Add support for Bearer Authorization header / token-based auth at Git commands. +- 3f1316f1c5: User Bearer Authorization header at Git commands with token-based auth at Bitbucket Server. +- eeff5046ae: Updated `publish:gitlab:merge-request` action to allow commit updates and deletes +- 692d5d3405: Added `reviewers` and `teamReviewers` parameters to `publish:github:pull-request` action to add reviewers on the pull request created by the action + +### Patch Changes + +- fc8a5f797b: Add a `publish:gerrit:review` scaffolder action +- c971afbf21: The `publish:file` action has been deprecated in favor of testing templates using the template editor instead. Note that this action is not and was never been installed by default. +- b10b6c4aa4: Fix issue on Windows where templated files where not properly skipped as intended. +- 56e1b4b89c: Fixed typos in alpha types. +- dad0f65494: Fail gracefully if an invalid `Authorization` header is passed to `POST /v2/tasks` +- 014b3b7776: Add missing `res.end()` in scaffolder backend `EventStream` usage +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-plugin-api@0.1.1 + - @backstage/plugin-catalog-node@1.0.1 + - @backstage/integration@1.3.0 + - @backstage/plugin-catalog-backend@1.3.1 + +## @backstage/plugin-shortcuts@0.3.0 + +### Minor Changes + +- 5b769fddb5: Internal observable replaced with a mapping from the storage API. This fixes shortcuts initialization when using firestore. + + `ShortcutApi.get` method, that returns an immediate snapshot of shortcuts, made public. + + Example of how to get and observe `shortcuts`: + + ```typescript + const shortcutApi = useApi(shortcutsApiRef); + const shortcuts = useObservable(shortcutApi.shortcut$(), shortcutApi.get()); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-sonarqube@0.4.0 + +### Minor Changes + +- 619b515172: **BREAKING** This plugin now call the `sonarqube-backend` plugin instead of relying on the proxy plugin + + The whole proxy's `'/sonarqube':` key can be removed from your configuration files. + + Then head to the [README in sonarqube-backend plugin page](https://github.com/backstage/backstage/tree/master/plugins/sonarqube-backend/README.md) to learn how to set-up the link to your Sonarqube instances. + +### Patch Changes + +- f9c310a439: Add ability to provide an optional Sonarqube instance into the annotation in the `catalog-info.yaml` file +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-sonarqube-backend@0.1.0 + +### Minor Changes + +- e2be9ab3a4: Initial creation of the plugin + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/plugin-techdocs-node@1.3.0 + +### Minor Changes + +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer + +### Patch Changes + +- c8196bd37d: Fix AWS S3 404 NotFound error + + When reading an object from the S3 bucket through a stream, the aws-sdk getObject() API may throw a 404 NotFound Error with no error message or, in fact, any sort of HTTP-layer error responses. These fail the @backstage/error's assertError() checks, so they must be wrapped. The test for this case was also updated to match the wrapped error message. + +- f833344611: Bump default `TechDocs` image to `v1.1.0`, see the release [here](https://github.com/backstage/techdocs-container/releases/tag/v1.1.0). + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + +## @backstage/app-defaults@1.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/core-app-api@1.0.5 + - @backstage/plugin-permission-react@0.4.4 + +## @backstage/backend-plugin-api@0.1.1 + +### Patch Changes + +- 0599732ec0: Refactored experimental backend system with new type names. +- 34c2f5aca1: The factory returned by `createBackendPlugin` and `createBackendModule` no longer require a parameter to be passed if the options are optional. +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-tasks@0.3.4 + +## @backstage/backend-tasks@0.3.4 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/backend-test-utils@0.1.27 + +### Patch Changes + +- 0599732ec0: Refactored experimental backend system with new type names. +- 56e1b4b89c: Added alpha test helpers for the new experimental backend system. +- Updated dependencies + - @backstage/cli@0.18.1 + - @backstage/backend-common@0.15.0 + - @backstage/backend-app-api@0.2.0 + - @backstage/backend-plugin-api@0.1.1 + +## @backstage/cli@0.18.1 + +### Patch Changes + +- d45bbfeb69: Linting is now ignored for any `.eslintrc.*` files, not just `.eslintrc.js`. +- 72c228fdb8: Fixed a bug where `NODE_ENV` was not set in the environment when starting the backend in development mode. It has always been the case that Webpack transformed `NODE_ENV` when running in development mode, but this did not affect dependencies in `node_modules` as they are treated as external. +- a539564c0d: Added Backstage version to output of `yarn backstage-cli info` command +- fd68d6f138: Added resolution of `.json` and `.wasm` files to the Webpack configuration in order to match defaults. +- 94155a41e0: Updated dependencies `@svgr/*` to `6.3.x`. + +## @backstage/core-app-api@1.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + +## @backstage/core-plugin-api@1.0.5 + +### Patch Changes + +- 80da5162c7: Introduced a new experimental feature that allows you to declare plugin-wide options for your plugin by defining + `__experimentalConfigure` in your `createPlugin` options. See for more information. + + This is an experimental feature and it will have breaking changes in the future. + +- 87649a06bf: Add a note that the `fetchApi` utility should not be used on sign-in page implementations and similar. + +## @backstage/create-app@0.4.30 + +### Patch Changes + +- 73cee58fc2: Bumped create-app version. + +- f762386d48: Bumped create-app version. + +- b162bbf464: Bumped create-app version. + +- db76fc6255: The `better-sqlite3` dependency has been moved back to production `"dependencies"` in `packages/backend/package.json`, with instructions in the Dockerfile to move it to `"devDependencies"` if desired. There is no need to apply this change to existing apps, unless you want your production image to have SQLite available as a database option. + +- ab9edd8b58: Updated backend to write stack trace when the backend fails to start up. + + To apply this change to your Backstage installation, make the following change to `packages/backend/src/index.ts` + + ```diff + cors: + origin: http://localhost:3000 + - console.error(`Backend failed to start up, ${error}`); + + console.error('Backend failed to start up', error); + ``` + +- 0174a0a022: Add `PATCH` and `HEAD` to the `Access-Control-Allow-Methods`. + + To apply this change to your Backstage installation make the following change to your `app-config.yaml` + + ```diff + cors: + origin: http://localhost:3000 + - methods: [GET, POST, PUT, DELETE] + + methods: [GET, POST, PUT, DELETE, PATCH, HEAD] + ``` + +## @backstage/dev-utils@1.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/app-defaults@1.0.5 + - @backstage/core-app-api@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/test-utils@1.1.3 + +## @backstage/integration-react@1.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/test-utils@1.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + - @backstage/core-app-api@1.0.5 + - @backstage/plugin-permission-react@0.4.4 + +## @backstage/plugin-airbrake@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/dev-utils@1.0.5 + - @backstage/test-utils@1.1.3 + +## @backstage/plugin-airbrake-backend@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/plugin-allure@0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-analytics-module-ga@0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-apache-airflow@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-api-docs@0.8.8 + +### Patch Changes + +- dae12c71cf: Updated dependency `@asyncapi/react-component` to `1.0.0-next.40`. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog@1.5.0 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-apollo-explorer@0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-app-backend@0.3.35 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/plugin-auth-backend@0.15.1 + +### Patch Changes + +- c676a9e07b: Fixed a bug in auth plugin on the backend where it ignores the skip migration database options when using the database provider. +- 2d7d6028e1: Updated dependency `@google-cloud/firestore` to `^6.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-auth-node@0.2.4 + +## @backstage/plugin-auth-node@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/plugin-azure-devops@0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-azure-devops-backend@0.3.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/plugin-badges@0.2.32 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-badges-backend@0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/plugin-bazaar@0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.18.1 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog@1.5.0 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-bazaar-backend@0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-test-utils@0.1.27 + +## @backstage/plugin-bitbucket-cloud-common@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + +## @backstage/plugin-bitrise@0.1.35 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-catalog-backend@1.3.1 + +### Patch Changes + +- 56e1b4b89c: Fixed typos in alpha types. + +- e3d3018531: Fix issue for conditional decisions based on properties stored as arrays, like tags. + + Before this change, having a permission policy returning conditional decisions based on metadata like tags, such like `createCatalogConditionalDecision(permission, catalogConditions.hasMetadata('tags', 'java'),)`, was producing wrong results. The issue occurred when authorizing entities already loaded from the database, for example when authorizing `catalogEntityDeletePermission`. + +- 059ae348b4: Use the non-deprecated form of table.unique in knex + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-plugin-api@0.1.1 + - @backstage/plugin-catalog-node@1.0.1 + - @backstage/integration@1.3.0 + - @backstage/plugin-catalog-common@1.0.5 + - @backstage/plugin-permission-node@0.6.4 + +## @backstage/plugin-catalog-backend-module-aws@0.1.8 + +### Patch Changes + +- 17d45dbf10: Deprecate `AwsS3DiscoveryProcessor` in favor of `AwsS3EntityProvider` (since v0.1.4). + + You can find a migration guide at + [the release notes for v0.1.4](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-aws/CHANGELOG.md#014). + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## @backstage/plugin-catalog-backend-module-azure@0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/plugin-catalog-backend@1.3.1 + - @backstage/plugin-bitbucket-cloud-common@0.1.2 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + - @backstage/plugin-bitbucket-cloud-common@0.1.2 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## @backstage/plugin-catalog-backend-module-github@0.1.6 + +### Patch Changes + +- f48950e34b: Github Entity Provider functionality for adding entities to the catalog. + + This provider replaces the GithubDiscoveryProcessor functionality as providers offer more flexibility with scheduling ingestion, removing and preventing orphaned entities. + + More information can be found on the [GitHub Discovery](https://backstage.io/docs/integrations/github/discovery) page. + +- c59d1ce487: Fixed bug where repository filter was including all archived repositories + +- 97f0a37378: Improved support for wildcards in `catalogPath` + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## @backstage/plugin-catalog-backend-module-gitlab@0.1.6 + +### Patch Changes + +- 24979413a4: Enhancing GitLab provider with filtering projects by pattern RegExp + + ```yaml + providers: + gitlab: + stg: + host: gitlab.stg.company.io + branch: main + projectPattern: 'john/' # new option + entityFilename: template.yaml + ``` + + With the aforementioned parameter you can filter projects, and keep only who belongs to the namespace "john". + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## @backstage/plugin-catalog-backend-module-msgraph@0.4.1 + +### Patch Changes + +- b1995df9f3: Adjust references in deprecation warnings to point to stable URL/document. +- Updated dependencies + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.1 + +### Patch Changes + +- b50e8e533b: Add an `$openapi` placeholder resolver that supports more use cases for resolving `$ref` instances. This means that the quite recently added `OpenApiRefProcessor` has been deprecated in favor of the `openApiPlaceholderResolver`. + + An example of how to use it can be seen below. + + ```yaml + apiVersion: backstage.io/v1alpha1 + kind: API + metadata: + name: example + description: Example API + spec: + type: openapi + lifecycle: production + owner: team + definition: + $openapi: ./spec/openapi.yaml # by using $openapi Backstage will now resolve all $ref instances + ``` + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-catalog-node@1.0.1 + - @backstage/integration@1.3.0 + - @backstage/plugin-catalog-backend@1.3.1 + +## @backstage/plugin-catalog-common@1.0.5 + +### Patch Changes + +- 92103db537: Export aggregated list of all catalog permissions + +## @backstage/plugin-catalog-graph@0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-catalog-graphql@0.3.12 + +### Patch Changes + +- fa3eeee92d: Updated dependency `@graphql-tools/schema` to `^9.0.0`. + +## @backstage/plugin-catalog-import@0.8.11 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/integration-react@1.1.3 + +## @backstage/plugin-catalog-node@1.0.1 + +### Patch Changes + +- 0599732ec0: Refactored experimental backend system with new type names. +- 56e1b4b89c: Fixed typos in alpha types. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.1 + +## @backstage/plugin-catalog-react@1.1.3 + +### Patch Changes + +- 44e691a7f9: Modify description column to not use auto width. +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-common@1.0.5 + - @backstage/plugin-permission-react@0.4.4 + +## @backstage/plugin-cicd-statistics@0.1.10 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-cicd-statistics@0.1.10 + +## @backstage/plugin-circleci@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-cloudbuild@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-code-climate@0.1.8 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- 831a8fee86: Send Authorization headers in fetch requests using FetchApi in Code Climate plugin to fix unauthorized requests to Backstage backends with authentication enabled. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-code-coverage@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-code-coverage-backend@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + +## @backstage/plugin-codescene@0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-config-schema@0.1.31 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-cost-insights@0.11.30 + +### Patch Changes + +- b746eca638: Make `products` field optional in the config +- daf4b33e34: Add name property to Group +- 08562ebe11: Display minus sign in trends in `CostOverviewCard` +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-cost-insights-common@0.1.1 + +## @backstage/plugin-cost-insights-common@0.1.1 + +### Patch Changes + +- daf4b33e34: Add name property to Group + +## @backstage/plugin-dynatrace@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-explore@0.3.39 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-explore-react@0.0.20 + +## @backstage/plugin-explore-react@0.0.20 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-firehydrant@0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-fossa@0.2.40 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-gcalendar@0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-gcp-projects@0.3.27 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-git-release-manager@0.3.21 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-github-actions@0.5.8 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-github-deployments@0.1.39 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/integration-react@1.1.3 + +## @backstage/plugin-github-pull-requests-board@0.1.2 + +### Patch Changes + +- 73268a67ff: Fixed rendering when PR contains references to deleted Github accounts +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-gitops-profiles@0.3.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-gocd@0.1.14 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-graphiql@0.2.40 + +### Patch Changes + +- 3a8ab72248: Minor internal tweak to lazy loading in order to improve module compatibility. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-graphql-backend@0.1.25 + +### Patch Changes + +- fa3eeee92d: Updated dependency `@graphql-tools/schema` to `^9.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-catalog-graphql@0.3.12 + +## @backstage/plugin-home@0.4.24 + +### Patch Changes + +- df7b9158b8: Add wrap-around for the listing of tools to prevent increasing width with name length. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-stack-overflow@0.1.4 + +## @backstage/plugin-ilert@0.1.34 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-jenkins@0.7.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-jenkins-common@0.1.7 + +## @backstage/plugin-jenkins-backend@0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-auth-node@0.2.4 + - @backstage/plugin-jenkins-common@0.1.7 + +## @backstage/plugin-jenkins-common@0.1.7 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.5 + +## @backstage/plugin-kafka@0.3.8 + +### Patch Changes + +- bde245f0bf: Add dashboard URL feature and fix minor styling issues. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-kafka-backend@0.2.28 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/plugin-kubernetes@0.7.1 + +### Patch Changes + +- 860ed68343: Fixed bug in CronJobsAccordions component that causes an error when cronjobs use a kubernetes alias, such as `@hourly` or `@daily` instead of standard cron syntax. +- f563b86a5b: Adds namespace column to Kubernetes error reporting table +- Updated dependencies + - @backstage/plugin-kubernetes-common@0.4.1 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-kubernetes-backend@0.7.1 + +### Patch Changes + +- 0297da83c0: Added `DaemonSets` to the default kubernetes resources. +- 0cd87cf30d: Added a new `customResources` field to the ClusterDetails interface, in order to specify (override) custom resources per cluster +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-kubernetes-common@0.4.1 + - @backstage/plugin-auth-node@0.2.4 + +## @backstage/plugin-kubernetes-common@0.4.1 + +### Patch Changes + +- 0297da83c0: Added `DaemonSets` to the default kubernetes resources. + +## @backstage/plugin-lighthouse@0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-newrelic@0.3.26 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-newrelic-dashboard@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-org@0.5.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-pagerduty@0.5.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-periskop@0.1.6 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-periskop-backend@0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/plugin-permission-backend@0.5.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-auth-node@0.2.4 + - @backstage/plugin-permission-node@0.6.4 + +## @backstage/plugin-permission-node@0.6.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-auth-node@0.2.4 + +## @backstage/plugin-permission-react@0.4.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-proxy-backend@0.2.29 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/plugin-rollbar@0.4.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-rollbar-backend@0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/plugin-scaffolder-backend@1.5.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/plugin-scaffolder-backend@1.5.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.5.0 + +## @backstage/plugin-search@1.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## @backstage/plugin-search-backend@1.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-auth-node@0.2.4 + - @backstage/plugin-permission-node@0.6.4 + - @backstage/plugin-search-backend-node@1.0.1 + +## @backstage/plugin-search-backend-module-elasticsearch@1.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.1 + +## @backstage/plugin-search-backend-module-pg@0.3.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-search-backend-node@1.0.1 + +## @backstage/plugin-search-backend-node@1.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-tasks@0.3.4 + +## @backstage/plugin-search-react@1.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-sentry@0.4.1 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-splunk-on-call@0.3.32 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-stack-overflow@0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.4.24 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-stack-overflow-backend@0.1.4 + +### Patch Changes + +- ea5631a8b2: Added API key as separate configuration + +## @backstage/plugin-tech-insights@0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-tech-insights-common@0.2.6 + +## @backstage/plugin-tech-insights-backend@0.5.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-tech-insights-common@0.2.6 + - @backstage/plugin-tech-insights-node@0.3.3 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-tech-insights-common@0.2.6 + - @backstage/plugin-tech-insights-node@0.3.3 + +## @backstage/plugin-tech-insights-common@0.2.6 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. + +## @backstage/plugin-tech-insights-node@0.3.3 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-tech-insights-common@0.2.6 + +## @backstage/plugin-tech-radar@0.5.15 + +### Patch Changes + +- a641f79dcb: Move CSS overflow property to quadrant block element (i.e. to a div element) in RadarLegend component. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-techdocs@1.3.1 + +### Patch Changes + +- e924d2d013: Added back reduction in size, this fixes the extremely large TeachDocs headings +- b86ed4d990: Add highlight to active navigation item and navigation parents. +- 7a98c73dc8: Fixed techdocs sidebar layout bug for medium devices. +- 8acb22205c: Scroll techdocs navigation into focus and expand any nested navigation items. +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.3.1 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog@1.5.0 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/core-app-api@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/test-utils@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## @backstage/plugin-techdocs-backend@1.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/plugin-techdocs-node@1.3.0 + - @backstage/plugin-catalog-common@1.0.5 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.3 + +### Patch Changes + +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/integration-react@1.1.3 + +## @backstage/plugin-techdocs-react@1.0.3 + +### Patch Changes + +- 29d6cf0147: Add `toLowerEntityRefMaybe()` helper function for handling `techdocs.legacyUseCaseSensitiveTripletPaths` flag. + Pass modified `entityRef` to `TechDocsReaderPageContext` to handle the `techdocs.legacyUseCaseSensitiveTripletPaths` flag. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-todo@0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-todo-backend@0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + +## @backstage/plugin-user-settings@0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @backstage/plugin-vault@0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## @backstage/plugin-vault-backend@0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-test-utils@0.1.27 + - @backstage/backend-tasks@0.3.4 + +## @backstage/plugin-xcmetrics@0.2.28 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## example-app@0.2.74 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes@0.7.1 + - @backstage/cli@0.18.1 + - @backstage/plugin-techdocs@1.3.1 + - @backstage/plugin-home@0.4.24 + - @backstage/core-components@0.11.0 + - @backstage/plugin-scaffolder@1.5.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-cost-insights@0.11.30 + - @backstage/plugin-graphiql@0.2.40 + - @backstage/plugin-catalog-common@1.0.5 + - @backstage/plugin-kafka@0.3.8 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.3 + - @backstage/plugin-gocd@0.1.14 + - @backstage/plugin-sentry@0.4.1 + - @backstage/plugin-api-docs@0.8.8 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/plugin-shortcuts@0.3.0 + - @backstage/plugin-tech-radar@0.5.15 + - @backstage/app-defaults@1.0.5 + - @backstage/core-app-api@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-airbrake@0.3.8 + - @backstage/plugin-apache-airflow@0.2.1 + - @backstage/plugin-azure-devops@0.1.24 + - @backstage/plugin-badges@0.2.32 + - @internal/plugin-catalog-customized@0.0.1 + - @backstage/plugin-catalog-graph@0.2.20 + - @backstage/plugin-catalog-import@0.8.11 + - @backstage/plugin-circleci@0.3.8 + - @backstage/plugin-cloudbuild@0.3.8 + - @backstage/plugin-code-coverage@0.2.1 + - @backstage/plugin-dynatrace@0.1.2 + - @backstage/plugin-explore@0.3.39 + - @backstage/plugin-gcalendar@0.3.4 + - @backstage/plugin-gcp-projects@0.3.27 + - @backstage/plugin-github-actions@0.5.8 + - @backstage/plugin-jenkins@0.7.7 + - @backstage/plugin-lighthouse@0.3.8 + - @backstage/plugin-newrelic@0.3.26 + - @backstage/plugin-newrelic-dashboard@0.2.1 + - @backstage/plugin-org@0.5.8 + - @backstage/plugin-pagerduty@0.5.1 + - @backstage/plugin-permission-react@0.4.4 + - @backstage/plugin-rollbar@0.4.8 + - @backstage/plugin-search@1.0.1 + - @backstage/plugin-search-react@1.0.1 + - @backstage/plugin-stack-overflow@0.1.4 + - @backstage/plugin-tech-insights@0.2.4 + - @backstage/plugin-todo@0.2.10 + - @backstage/plugin-user-settings@0.4.7 + +## example-backend@0.2.74 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-kubernetes-backend@0.7.1 + - @backstage/integration@1.3.0 + - @backstage/plugin-scaffolder-backend@1.5.0 + - @backstage/plugin-auth-backend@0.15.1 + - @backstage/plugin-graphql-backend@0.1.25 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-tech-insights-node@0.3.3 + - @backstage/plugin-catalog-backend@1.3.1 + - example-app@0.2.74 + - @backstage/plugin-app-backend@0.3.35 + - @backstage/plugin-auth-node@0.2.4 + - @backstage/plugin-azure-devops-backend@0.3.14 + - @backstage/plugin-badges-backend@0.1.29 + - @backstage/plugin-code-coverage-backend@0.2.1 + - @backstage/plugin-jenkins-backend@0.1.25 + - @backstage/plugin-kafka-backend@0.2.28 + - @backstage/plugin-permission-backend@0.5.10 + - @backstage/plugin-permission-node@0.6.4 + - @backstage/plugin-proxy-backend@0.2.29 + - @backstage/plugin-rollbar-backend@0.1.32 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.3 + - @backstage/plugin-search-backend@1.0.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.1 + - @backstage/plugin-search-backend-module-pg@0.3.6 + - @backstage/plugin-search-backend-node@1.0.1 + - @backstage/plugin-tech-insights-backend@0.5.1 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.19 + - @backstage/plugin-techdocs-backend@1.2.1 + - @backstage/plugin-todo-backend@0.1.32 + +## example-backend-next@0.0.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.5.0 + - @backstage/backend-defaults@0.1.0 + - @backstage/plugin-catalog-backend@1.3.1 + +## techdocs-cli-embedded-app@0.2.73 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.18.1 + - @backstage/plugin-techdocs@1.3.1 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog@1.5.0 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/app-defaults@1.0.5 + - @backstage/core-app-api@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/test-utils@1.1.3 + +## @internal/plugin-catalog-customized@0.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.5.0 + - @backstage/plugin-catalog-react@1.1.3 + +## @internal/plugin-todo-list@1.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## @internal/plugin-todo-list-backend@1.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-auth-node@0.2.4 diff --git a/docs/releases/v1.5.0-next.0-changelog.md b/docs/releases/v1.5.0-next.0-changelog.md new file mode 100644 index 0000000000..72ca02de50 --- /dev/null +++ b/docs/releases/v1.5.0-next.0-changelog.md @@ -0,0 +1,1400 @@ +# Release v1.5.0-next.0 + +## @backstage/backend-common@0.15.0-next.0 + +### Minor Changes + +- 12e9b54f0e: Added back support for when no branch is provided to the `UrlReader` for Bitbucket Server +- 30012e7d8c: - Added `force` and `remoteRef` option to `push` method in `git` actions + - Added `addRemote` and `deleteRemote` methods to `git` actions + +### Patch Changes + +- fc8a5f797b: Improve `scm/git` wrapper around `isomorphic-git` library : + + - Add `checkout` function, + - Add optional `remoteRef` parameter in the `push` function. + +- 3b7930b3e5: Add support for Bearer Authorization header / token-based auth at Git commands. + +- cfa078e255: The `ZipArchiveResponse` now correctly handles corrupt ZIP archives. + + Before this change, certain corrupt ZIP archives either cause the inflater to throw (as expected), or will hang the parser indefinitely. + + By switching out the `zip` parsing library, we now write to a temporary directory, and load from disk which should ensure that the parsing of the `.zip` files are done correctly because `streaming` of `zip` paths is technically impossible without being able to parse the headers at the end of the file. + +- 770d3f92c4: The config prop `ensureExists` now applies to schema creation when `pluginDivisionMode` is set to `schema`. This means schemas will no longer accidentally be automatically created when `ensureExists` is set to `false`. + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + +## @backstage/integration@1.3.0-next.0 + +### Minor Changes + +- 593dea6710: Add support for Basic Auth for Bitbucket Server. + +### Patch Changes + +- 163243a4d1: Handle incorrect return type from Octokit paginate plugin to resolve reading URLs from GitHub +- c4b460a47d: Avoid double encoding of the file path in `getBitbucketDownloadUrl` +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. + +## @backstage/plugin-catalog@1.5.0-next.0 + +### Minor Changes + +- 80da5162c7: Plugin catalog has been modified to use an experimental feature where you can customize the title of the create button. + + You can modify it by doing: + + ```typescript jsx + import { catalogPlugin } from '@backstage/plugin-catalog'; + + catalogPlugin.__experimentalReconfigure({ + createButtonTitle: 'New', + }); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + +## @backstage/plugin-scaffolder-backend@1.5.0-next.0 + +### Minor Changes + +- 593dea6710: Add support for Basic Auth for Bitbucket Server. +- 3b7930b3e5: Add support for Bearer Authorization header / token-based auth at Git commands. +- 3f1316f1c5: User Bearer Authorization header at Git commands with token-based auth at Bitbucket Server. +- eeff5046ae: Updated `publish:gitlab:merge-request` action to allow commit updates and deletes + +### Patch Changes + +- fc8a5f797b: Add a `publish:gerrit:review` scaffolder action +- 014b3b7776: Add missing `res.end()` in scaffolder backend `EventStream` usage +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-plugin-api@0.1.1-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + - @backstage/plugin-catalog-node@1.0.1-next.0 + +## @backstage/plugin-shortcuts@0.3.0-next.0 + +### Minor Changes + +- 5b769fddb5: Internal observable replaced with a mapping from the storage API. This fixes shortcuts initialization when using firestore. + + `ShortcutApi.get` method, that returns an immediate snapshot of shortcuts, made public. + + Example of how to get and observe `shortcuts`: + + ```typescript + const shortcutApi = useApi(shortcutsApiRef); + const shortcuts = useObservable(shortcutApi.shortcut$(), shortcutApi.get()); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/app-defaults@1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-permission-react@0.4.4-next.0 + +## @backstage/backend-app-api@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/backend-plugin-api@0.1.1-next.0 + - @backstage/plugin-permission-node@0.6.4-next.0 + +## @backstage/backend-plugin-api@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + +## @backstage/backend-tasks@0.3.4-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/backend-test-utils@0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/cli@0.18.1-next.0 + +## @backstage/cli@0.18.1-next.0 + +### Patch Changes + +- a539564c0d: Added Backstage version to output of `yarn backstage-cli info` command +- 94155a41e0: Updated dependencies `@svgr/*` to `6.3.x`. + +## @backstage/core-app-api@1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + +## @backstage/core-components@0.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + +## @backstage/core-plugin-api@1.0.5-next.0 + +### Patch Changes + +- 80da5162c7: Introduced a new experimental feature that allows you to declare plugin-wide options for your plugin by defining + `__experimentalConfigure` in your `createPlugin` options. See for more information. + + This is an experimental feature and it will have breaking changes in the future. + +## @backstage/create-app@0.4.30-next.0 + +### Patch Changes + +- Bumped create-app version. + +## @backstage/dev-utils@1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/app-defaults@1.0.5-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/test-utils@1.1.3-next.0 + +## @backstage/integration-react@1.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @techdocs/cli@1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-techdocs-node@1.2.1-next.0 + +## @backstage/test-utils@1.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/plugin-permission-react@0.4.4-next.0 + +## @backstage/plugin-adr@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-adr-common@0.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + +## @backstage/plugin-adr-backend@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-adr-common@0.1.3-next.0 + +## @backstage/plugin-adr-common@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + +## @backstage/plugin-airbrake@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/dev-utils@1.0.5-next.0 + - @backstage/test-utils@1.1.3-next.0 + +## @backstage/plugin-airbrake-backend@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/plugin-allure@0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-analytics-module-ga@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-apache-airflow@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-api-docs@0.8.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog@1.5.0-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-apollo-explorer@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-app-backend@0.3.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/plugin-auth-backend@0.15.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 + +## @backstage/plugin-auth-node@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/plugin-azure-devops@0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-azure-devops-backend@0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/plugin-badges@0.2.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-badges-backend@0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/plugin-bazaar@0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog@1.5.0-next.0 + - @backstage/cli@0.18.1-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-bazaar-backend@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-test-utils@0.1.27-next.0 + +## @backstage/plugin-bitbucket-cloud-common@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + +## @backstage/plugin-bitrise@0.1.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-catalog-backend@1.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-plugin-api@0.1.1-next.0 + - @backstage/plugin-catalog-node@1.0.1-next.0 + - @backstage/plugin-permission-node@0.6.4-next.0 + +## @backstage/plugin-catalog-backend-module-aws@0.1.8-next.0 + +### Patch Changes + +- 17d45dbf10: Deprecate `AwsS3DiscoveryProcessor` in favor of `AwsS3EntityProvider` (since v0.1.4). + + You can find a migration guide at + [the release notes for v0.1.4](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-aws/CHANGELOG.md#014). + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## @backstage/plugin-catalog-backend-module-azure@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket@0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.1.2-next.0 + +## @backstage/plugin-catalog-backend-module-bitbucket-cloud@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.1.2-next.0 + +## @backstage/plugin-catalog-backend-module-gerrit@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## @backstage/plugin-catalog-backend-module-github@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## @backstage/plugin-catalog-backend-module-gitlab@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## @backstage/plugin-catalog-backend-module-ldap@0.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## @backstage/plugin-catalog-backend-module-msgraph@0.4.1-next.0 + +### Patch Changes + +- b1995df9f3: Adjust references in deprecation warnings to point to stable URL/document. +- Updated dependencies + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## @backstage/plugin-catalog-backend-module-openapi@0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## @backstage/plugin-catalog-graph@0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-catalog-import@0.8.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-catalog-node@1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.1-next.0 + +## @backstage/plugin-catalog-react@1.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-permission-react@0.4.4-next.0 + +## @backstage/plugin-cicd-statistics@0.1.10-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + +## @backstage/plugin-cicd-statistics-module-gitlab@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-cicd-statistics@0.1.10-next.0 + +## @backstage/plugin-circleci@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-cloudbuild@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-code-climate@0.1.8-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-code-coverage@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-code-coverage-backend@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + +## @backstage/plugin-codescene@0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-config-schema@0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-cost-insights@0.11.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-dynatrace@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-explore@0.3.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-explore-react@0.0.20-next.0 + +## @backstage/plugin-explore-react@0.0.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + +## @backstage/plugin-firehydrant@0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-fossa@0.2.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-gcalendar@0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-gcp-projects@0.3.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-git-release-manager@0.3.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-github-actions@0.5.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-github-deployments@0.1.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-github-pull-requests-board@0.1.2-next.0 + +### Patch Changes + +- 73268a67ff: Fixed rendering when PR contains references to deleted Github accounts +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-gitops-profiles@0.3.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-gocd@0.1.14-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-graphiql@0.2.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-graphql-backend@0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/plugin-home@0.4.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-stack-overflow@0.1.4-next.0 + +## @backstage/plugin-ilert@0.1.34-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-jenkins@0.7.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-jenkins-backend@0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 + +## @backstage/plugin-kafka@0.3.8-next.0 + +### Patch Changes + +- bde245f0bf: Add dashboard URL feature and fix minor styling issues. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-kafka-backend@0.2.28-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/plugin-kubernetes@0.7.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-kubernetes-backend@0.7.1-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 + +## @backstage/plugin-lighthouse@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-newrelic@0.3.26-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-newrelic-dashboard@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-org@0.5.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-pagerduty@0.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-periskop@0.1.6-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-periskop-backend@0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/plugin-permission-backend@0.5.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 + - @backstage/plugin-permission-node@0.6.4-next.0 + +## @backstage/plugin-permission-node@0.6.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 + +## @backstage/plugin-permission-react@0.4.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + +## @backstage/plugin-proxy-backend@0.2.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/plugin-rollbar@0.4.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-rollbar-backend@0.1.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## @backstage/plugin-scaffolder@1.4.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-permission-react@0.4.4-next.0 + +## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-scaffolder-backend@1.5.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-rails@0.4.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-scaffolder-backend@1.5.0-next.0 + +## @backstage/plugin-scaffolder-backend-module-yeoman@0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.5.0-next.0 + +## @backstage/plugin-search@1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + +## @backstage/plugin-search-backend@1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 + - @backstage/plugin-permission-node@0.6.4-next.0 + - @backstage/plugin-search-backend-node@1.0.1-next.0 + +## @backstage/plugin-search-backend-module-elasticsearch@1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-backend-node@1.0.1-next.0 + +## @backstage/plugin-search-backend-module-pg@0.3.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-search-backend-node@1.0.1-next.0 + +## @backstage/plugin-search-backend-node@1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + +## @backstage/plugin-search-react@1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-sentry@0.4.1-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-sonarqube@0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-splunk-on-call@0.3.32-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-stack-overflow@0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-home@0.4.24-next.0 + +## @backstage/plugin-stack-overflow-backend@0.1.4-next.0 + +### Patch Changes + +- ea5631a8b2: Added API key as separate configuration + +## @backstage/plugin-tech-insights@0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-tech-insights-common@0.2.6-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-tech-insights-backend@0.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-tech-insights-common@0.2.6-next.0 + - @backstage/plugin-tech-insights-node@0.3.3-next.0 + +## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-tech-insights-common@0.2.6-next.0 + - @backstage/plugin-tech-insights-node@0.3.3-next.0 + +## @backstage/plugin-tech-insights-common@0.2.6-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. + +## @backstage/plugin-tech-insights-node@0.3.3-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-tech-insights-common@0.2.6-next.0 + +## @backstage/plugin-tech-radar@0.5.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-techdocs@1.3.1-next.0 + +### Patch Changes + +- 7a98c73dc8: Fixed techdocs sidebar layout bug for medium devices. +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog@1.5.0-next.0 + - @backstage/plugin-techdocs@1.3.1-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/test-utils@1.1.3-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + +## @backstage/plugin-techdocs-backend@1.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-techdocs-node@1.2.1-next.0 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + +## @backstage/plugin-techdocs-node@1.2.1-next.0 + +### Patch Changes + +- c8196bd37d: Fix AWS S3 404 NotFound error + + When reading an object from the S3 bucket through a stream, the aws-sdk getObject() API may throw a 404 NotFound Error with no error message or, in fact, any sort of HTTP-layer error responses. These fail the @backstage/error's assertError() checks, so they must be wrapped. The test for this case was also updated to match the wrapped error message. + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + +## @backstage/plugin-techdocs-react@1.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-todo@0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-todo-backend@0.1.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + +## @backstage/plugin-user-settings@0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-vault@0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @backstage/plugin-vault-backend@0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/backend-test-utils@0.1.27-next.0 + +## @backstage/plugin-xcmetrics@0.2.28-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## example-app@0.2.74-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-techdocs@1.3.1-next.0 + - @backstage/cli@0.18.1-next.0 + - @backstage/plugin-kafka@0.3.8-next.0 + - @backstage/plugin-gocd@0.1.14-next.0 + - @backstage/plugin-sentry@0.4.1-next.0 + - @backstage/plugin-shortcuts@0.3.0-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-import@0.8.11-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/plugin-github-actions@0.5.8-next.0 + - @backstage/plugin-scaffolder@1.4.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.3-next.0 + - @backstage/app-defaults@1.0.5-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-airbrake@0.3.8-next.0 + - @backstage/plugin-apache-airflow@0.2.1-next.0 + - @backstage/plugin-api-docs@0.8.8-next.0 + - @backstage/plugin-azure-devops@0.1.24-next.0 + - @backstage/plugin-badges@0.2.32-next.0 + - @backstage/plugin-catalog-graph@0.2.20-next.0 + - @backstage/plugin-circleci@0.3.8-next.0 + - @backstage/plugin-cloudbuild@0.3.8-next.0 + - @backstage/plugin-code-coverage@0.2.1-next.0 + - @backstage/plugin-cost-insights@0.11.30-next.0 + - @backstage/plugin-dynatrace@0.1.2-next.0 + - @backstage/plugin-explore@0.3.39-next.0 + - @backstage/plugin-gcalendar@0.3.4-next.0 + - @backstage/plugin-gcp-projects@0.3.27-next.0 + - @backstage/plugin-graphiql@0.2.40-next.0 + - @backstage/plugin-home@0.4.24-next.0 + - @backstage/plugin-jenkins@0.7.7-next.0 + - @backstage/plugin-kubernetes@0.7.1-next.0 + - @backstage/plugin-lighthouse@0.3.8-next.0 + - @backstage/plugin-newrelic@0.3.26-next.0 + - @backstage/plugin-newrelic-dashboard@0.2.1-next.0 + - @backstage/plugin-org@0.5.8-next.0 + - @backstage/plugin-pagerduty@0.5.1-next.0 + - @backstage/plugin-permission-react@0.4.4-next.0 + - @backstage/plugin-rollbar@0.4.8-next.0 + - @backstage/plugin-search@1.0.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + - @backstage/plugin-stack-overflow@0.1.4-next.0 + - @backstage/plugin-tech-insights@0.2.4-next.0 + - @backstage/plugin-tech-radar@0.5.15-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + - @backstage/plugin-todo@0.2.10-next.0 + - @backstage/plugin-user-settings@0.4.7-next.0 + - @internal/plugin-catalog-customized@0.0.1-next.0 + +## example-backend@0.2.74-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-scaffolder-backend@1.5.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-kubernetes-backend@0.7.1-next.0 + - @backstage/plugin-tech-insights-node@0.3.3-next.0 + - @backstage/plugin-app-backend@0.3.35-next.0 + - @backstage/plugin-auth-backend@0.15.1-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 + - @backstage/plugin-azure-devops-backend@0.3.14-next.0 + - @backstage/plugin-badges-backend@0.1.29-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + - @backstage/plugin-code-coverage-backend@0.2.1-next.0 + - @backstage/plugin-graphql-backend@0.1.25-next.0 + - @backstage/plugin-jenkins-backend@0.1.25-next.0 + - @backstage/plugin-kafka-backend@0.2.28-next.0 + - @backstage/plugin-permission-backend@0.5.10-next.0 + - @backstage/plugin-permission-node@0.6.4-next.0 + - @backstage/plugin-proxy-backend@0.2.29-next.0 + - @backstage/plugin-rollbar-backend@0.1.32-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.3-next.0 + - @backstage/plugin-search-backend@1.0.1-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.1-next.0 + - @backstage/plugin-search-backend-module-pg@0.3.6-next.0 + - @backstage/plugin-search-backend-node@1.0.1-next.0 + - @backstage/plugin-tech-insights-backend@0.5.1-next.0 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.19-next.0 + - @backstage/plugin-techdocs-backend@1.2.1-next.0 + - @backstage/plugin-todo-backend@0.1.32-next.0 + - example-app@0.2.74-next.0 + +## example-backend-next@0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.5.0-next.0 + - @backstage/backend-app-api@0.1.1-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## techdocs-cli-embedded-app@0.2.73-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog@1.5.0-next.0 + - @backstage/plugin-techdocs@1.3.1-next.0 + - @backstage/cli@0.18.1-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/app-defaults@1.0.5-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/test-utils@1.1.3-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + +## @internal/plugin-catalog-customized@0.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.5.0-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + +## @internal/plugin-todo-list@1.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## @internal/plugin-todo-list-backend@1.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 diff --git a/docs/releases/v1.5.0-next.1-changelog.md b/docs/releases/v1.5.0-next.1-changelog.md new file mode 100644 index 0000000000..deedd1dc44 --- /dev/null +++ b/docs/releases/v1.5.0-next.1-changelog.md @@ -0,0 +1,274 @@ +# Release v1.5.0-next.1 + +## @backstage/integration@1.3.0-next.1 + +### Minor Changes + +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer + +### Patch Changes + +- 1f27d83933: Fixed bug in getGitLabFileFetchUrl where a target whose path did not contain the + `/-/` scope would result in a fetch URL that did not support + private-token-based authentication. + +## @backstage/plugin-catalog@1.5.0-next.1 + +### Minor Changes + +- fe94398418: Allow changing the subtitle of the `CatalogTable` component + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## @backstage/plugin-scaffolder@1.5.0-next.1 + +### Minor Changes + +- c4b452e16a: Starting the implementation of the Wizard page for the `next` scaffolder plugin + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## @backstage/plugin-scaffolder-backend@1.5.0-next.1 + +### Minor Changes + +- c4b452e16a: Starting the implementation of the Wizard page for the `next` scaffolder plugin + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-catalog-backend@1.3.1-next.1 + +## @backstage/plugin-sonarqube@0.4.0-next.1 + +### Minor Changes + +- 619b515172: **BREAKING** This plugin now call the `sonarqube-backend` plugin instead of relying on the proxy plugin + + The whole proxy's `'/sonarqube':` key can be removed from your configuration files. + + Then head to the [README in sonarqube-backend plugin page](https://github.com/backstage/backstage/tree/master/plugins/sonarqube-backend/README.md) to learn how to set-up the link to your Sonarqube instances. + +### Patch Changes + +- f9c310a439: Add ability to provide an optional Sonarqube instance into the annotation in the `catalog-info.yaml` file +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## @backstage/plugin-sonarqube-backend@0.1.0-next.0 + +### Minor Changes + +- e2be9ab3a4: Initial creation of the plugin + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + +## @backstage/plugin-techdocs-node@1.3.0-next.1 + +### Minor Changes + +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer + +### Patch Changes + +- f833344611: Bump default `TechDocs` image to `v1.1.0`, see the release [here](https://github.com/backstage/techdocs-container/releases/tag/v1.1.0). +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + - @backstage/integration@1.3.0-next.1 + +## @backstage/backend-common@0.15.0-next.1 + +### Patch Changes + +- 1732a18a7a: Exported `redactLogLine` function to be able to use it in custom loggers and renamed it to `redactWinstonLogLine`. +- Updated dependencies + - @backstage/integration@1.3.0-next.1 + +## @backstage/core-components@0.10.1-next.1 + +### Patch Changes + +- a22af3edc8: Adding a `className` prop to the `MarkdownContent` component + +## @backstage/create-app@0.4.30-next.1 + +### Patch Changes + +- Bumped create-app version. + +## @techdocs/cli@1.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + - @backstage/plugin-techdocs-node@1.3.0-next.1 + +## @backstage/plugin-api-docs@0.8.8-next.1 + +### Patch Changes + +- dae12c71cf: Updated dependency `@asyncapi/react-component` to `1.0.0-next.40`. +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog@1.5.0-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## @backstage/plugin-catalog-backend@1.3.1-next.1 + +### Patch Changes + +- e3d3018531: Fix issue for conditional decisions based on properties stored as arrays, like tags. + + Before this change, having a permission policy returning conditional decisions based on metadata like tags, such like `createCatalogConditionalDecision(permission, catalogConditions.hasMetadata('tags', 'java'),)`, was producing wrong results. The issue occurred when authorizing entities already loaded from the database, for example when authorizing `catalogEntityDeletePermission`. + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/backend-common@0.15.0-next.1 + - @backstage/integration@1.3.0-next.1 + +## @backstage/plugin-catalog-backend-module-github@0.1.6-next.1 + +### Patch Changes + +- f48950e34b: Github Entity Provider functionality for adding entities to the catalog. + + This provider replaces the GithubDiscoveryProcessor functionality as providers offer more flexibility with scheduling ingestion, removing and preventing orphaned entities. + + More information can be found on the [GitHub Discovery](https://backstage.io/docs/integrations/github/discovery) page. + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-catalog-backend@1.3.1-next.1 + +## @backstage/plugin-catalog-common@1.0.5-next.0 + +### Patch Changes + +- 92103db537: Export aggregated list of all catalog permissions + +## @backstage/plugin-catalog-react@1.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/integration@1.3.0-next.1 + +## @backstage/plugin-home@0.4.24-next.1 + +### Patch Changes + +- df7b9158b8: Add wrap-around for the listing of tools to prevent increasing width with name length. +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## @backstage/plugin-jenkins@0.7.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + - @backstage/plugin-jenkins-common@0.1.7-next.0 + +## @backstage/plugin-jenkins-backend@0.1.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + - @backstage/plugin-jenkins-common@0.1.7-next.0 + +## @backstage/plugin-jenkins-common@0.1.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.5-next.0 + +## @backstage/plugin-kubernetes@0.7.1-next.1 + +### Patch Changes + +- 860ed68343: Fixed bug in CronJobsAccordions component that causes an error when cronjobs use a kubernetes alias, such as `@hourly` or `@daily` instead of standard cron syntax. +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## @backstage/plugin-techdocs@1.3.1-next.1 + +### Patch Changes + +- b86ed4d990: Add highlight to active navigation item and navigation parents. +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## @backstage/plugin-techdocs-backend@1.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/backend-common@0.15.0-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-techdocs-node@1.3.0-next.1 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.3-next.1 + +### Patch Changes + +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.1 + +## @backstage/plugin-techdocs-react@1.0.3-next.1 + +### Patch Changes + +- 29d6cf0147: Add `toLowerEntityRefMaybe()` helper function for handling `techdocs.legacyUseCaseSensitiveTripletPaths` flag. + Pass modified `entityRef` to `TechDocsReaderPageContext` to handle the `techdocs.legacyUseCaseSensitiveTripletPaths` flag. +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + +## example-app@0.2.74-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes@0.7.1-next.1 + - @backstage/plugin-home@0.4.24-next.1 + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-scaffolder@1.5.0-next.1 + - @backstage/plugin-techdocs@1.3.1-next.1 + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.3-next.1 + - @backstage/plugin-api-docs@0.8.8-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + - @backstage/plugin-jenkins@0.7.7-next.1 diff --git a/docs/releases/v1.5.0-next.2-changelog.md b/docs/releases/v1.5.0-next.2-changelog.md new file mode 100644 index 0000000000..4a17a46a24 --- /dev/null +++ b/docs/releases/v1.5.0-next.2-changelog.md @@ -0,0 +1,791 @@ +# Release v1.5.0-next.2 + +## @backstage/core-components@0.11.0-next.2 + +### Minor Changes + +- d0eefc499a: Made the `to` prop of `Button` and `Link` more strict, only supporting plain strings. It used to be the case that this prop was unexpectedly too liberal, making it look like we supported the complex `react-router-dom` object form of the parameter as well, which led to unexpected results at runtime. + +## @techdocs/cli@1.2.0-next.2 + +### Minor Changes + +- 855952db53: Added CLI option `--docker-option` to allow passing additional options to the `docker run` command executed my `serve` and `serve:mkdocs`. + +## @backstage/plugin-catalog-backend-module-bitbucket-server@0.1.0-next.0 + +### Minor Changes + +- f7607f9d85: Add new plugin catalog-backend-module-bitbucket-server which adds the `BitbucketServerEntityProvider`. + + The entity provider is meant as a replacement for the `BitbucketDiscoveryProcessor` to be used with Bitbucket Server (Bitbucket Cloud already has a replacement). + + **Before:** + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addProcessor( + BitbucketDiscoveryProcessor.fromConfig(env.config, { logger: env.logger }), + ); + ``` + + ```yaml + # app-config.yaml + catalog: + locations: + - type: bitbucket-discovery + target: 'https://bitbucket.mycompany.com/projects/*/repos/*/catalog-info.yaml + ``` + + **After:** + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addEntityProvider( + BitbucketServerEntityProvider.fromConfig(env.config, { + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + }), + ); + ``` + + ```yaml + # app-config.yaml + catalog: + providers: + bitbucketServer: + yourProviderId: # identifies your ingested dataset + catalogPath: /catalog-info.yaml # default value + filters: # optional + projectKey: '.*' # optional; RegExp + repoSlug: '.*' # optional; RegExp + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.1-next.2 + +## @backstage/plugin-github-issues@0.1.0-next.0 + +### Minor Changes + +- ffd5e47fb5: New plugin for displaying GitHub Issues added + +### Patch Changes + +- b522f49403: Updated dependency `@spotify/prettier-config` to `^14.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-scaffolder-backend@1.5.0-next.2 + +### Minor Changes + +- 692d5d3405: Added `reviewers` and `teamReviewers` parameters to `publish:github:pull-request` action to add reviewers on the pull request created by the action + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.1-next.2 + +## @backstage/app-defaults@1.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/cli@0.18.1-next.1 + +### Patch Changes + +- fd68d6f138: Added resolution of `.json` and `.wasm` files to the Webpack configuration in order to match defaults. + +## @backstage/create-app@0.4.30-next.2 + +### Patch Changes + +- 0174a0a022: Add `PATCH` and `HEAD` to the `Access-Control-Allow-Methods`. + + To apply this change to your Backstage installation make the following change to your `app-config.yaml` + + ```diff + cors: + origin: http://localhost:3000 + - methods: [GET, POST, PUT, DELETE] + + methods: [GET, POST, PUT, DELETE, PATCH, HEAD] + ``` + +## @backstage/dev-utils@1.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/app-defaults@1.0.5-next.1 + - @backstage/integration-react@1.1.3-next.1 + +## @backstage/integration-react@1.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-adr@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-search-react@1.0.1-next.1 + +## @backstage/plugin-airbrake@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/dev-utils@1.0.5-next.1 + +## @backstage/plugin-allure@0.1.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-analytics-module-ga@0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-apache-airflow@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-api-docs@0.8.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/plugin-catalog@1.5.0-next.2 + +## @backstage/plugin-apollo-explorer@0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-auth-backend@0.15.1-next.1 + +### Patch Changes + +- 2d7d6028e1: Updated dependency `@google-cloud/firestore` to `^6.0.0`. + +## @backstage/plugin-azure-devops@0.1.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-badges@0.2.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-bazaar@0.1.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/cli@0.18.1-next.1 + - @backstage/core-components@0.11.0-next.2 + - @backstage/plugin-catalog@1.5.0-next.2 + +## @backstage/plugin-bitrise@0.1.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-catalog@1.5.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-search-react@1.0.1-next.1 + +## @backstage/plugin-catalog-backend@1.3.1-next.2 + +### Patch Changes + +- 059ae348b4: Use the non-deprecated form of table.unique in knex + +## @backstage/plugin-catalog-backend-module-github@0.1.6-next.2 + +### Patch Changes + +- 97f0a37378: Improved support for wildcards in `catalogPath` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.1-next.2 + +## @backstage/plugin-catalog-backend-module-gitlab@0.1.6-next.1 + +### Patch Changes + +- 24979413a4: Enhancing GitLab provider with filtering projects by pattern RegExp + + ```yaml + providers: + gitlab: + stg: + host: gitlab.stg.company.io + branch: main + projectPattern: 'john/' # new option + entityFilename: template.yaml + ``` + + With the aforementioned parameter you can filter projects, and keep only who belongs to the namespace "john". + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.1-next.2 + +## @backstage/plugin-catalog-graph@0.2.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-catalog-import@0.8.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + +## @backstage/plugin-catalog-react@1.1.3-next.2 + +### Patch Changes + +- 44e691a7f9: Modify description column to not use auto width. +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-circleci@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-cloudbuild@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-code-climate@0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-code-coverage@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-codescene@0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-config-schema@0.1.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-cost-insights@0.11.30-next.1 + +### Patch Changes + +- b746eca638: Make `products` field optional in the config +- daf4b33e34: Add name property to Group +- Updated dependencies + - @backstage/plugin-cost-insights-common@0.1.1-next.0 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-cost-insights-common@0.1.1-next.0 + +### Patch Changes + +- daf4b33e34: Add name property to Group + +## @backstage/plugin-dynatrace@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-explore@0.3.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-firehydrant@0.1.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-fossa@0.2.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-gcalendar@0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-gcp-projects@0.3.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-git-release-manager@0.3.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-github-actions@0.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-github-deployments@0.1.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + +## @backstage/plugin-github-pull-requests-board@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-gitops-profiles@0.3.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-gocd@0.1.14-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-graphiql@0.2.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-home@0.4.24-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/plugin-stack-overflow@0.1.4-next.1 + +## @backstage/plugin-ilert@0.1.34-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-jenkins@0.7.7-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-kafka@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-kubernetes@0.7.1-next.2 + +### Patch Changes + +- f563b86a5b: Adds namespace column to Kubernetes error reporting table +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-kubernetes-backend@0.7.1-next.1 + +### Patch Changes + +- 0cd87cf30d: Added a new `customResources` field to the ClusterDetails interface, in order to specify (override) custom resources per cluster + +## @backstage/plugin-lighthouse@0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-newrelic@0.3.26-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-newrelic-dashboard@0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-org@0.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-pagerduty@0.5.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-periskop@0.1.6-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-rollbar@0.4.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-scaffolder@1.5.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + +## @backstage/plugin-search@1.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/plugin-search-react@1.0.1-next.1 + +## @backstage/plugin-search-react@1.0.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-sentry@0.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-shortcuts@0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-sonarqube@0.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-splunk-on-call@0.3.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-stack-overflow@0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + - @backstage/plugin-home@0.4.24-next.2 + +## @backstage/plugin-tech-insights@0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-tech-radar@0.5.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-techdocs@1.3.1-next.2 + +### Patch Changes + +- 8acb22205c: Scroll techdocs navigation into focus and expand any nested navigation items. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-search-react@1.0.1-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + +## @backstage/plugin-techdocs-addons-test-utils@1.0.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.3.1-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-catalog@1.5.0-next.2 + - @backstage/plugin-search-react@1.0.1-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + +## @backstage/plugin-techdocs-module-addons-contrib@1.0.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + +## @backstage/plugin-techdocs-react@1.0.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-todo@0.2.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-user-settings@0.4.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-vault@0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## @backstage/plugin-xcmetrics@0.2.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## example-app@0.2.74-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes@0.7.1-next.2 + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/plugin-cost-insights@0.11.30-next.1 + - @backstage/cli@0.18.1-next.1 + - @backstage/plugin-techdocs@1.3.1-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/app-defaults@1.0.5-next.1 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-airbrake@0.3.8-next.1 + - @backstage/plugin-apache-airflow@0.2.1-next.1 + - @backstage/plugin-api-docs@0.8.8-next.2 + - @backstage/plugin-azure-devops@0.1.24-next.1 + - @backstage/plugin-badges@0.2.32-next.1 + - @backstage/plugin-catalog-graph@0.2.20-next.1 + - @backstage/plugin-catalog-import@0.8.11-next.1 + - @backstage/plugin-circleci@0.3.8-next.1 + - @backstage/plugin-cloudbuild@0.3.8-next.1 + - @backstage/plugin-code-coverage@0.2.1-next.1 + - @backstage/plugin-dynatrace@0.1.2-next.1 + - @backstage/plugin-explore@0.3.39-next.1 + - @backstage/plugin-gcalendar@0.3.4-next.1 + - @backstage/plugin-gcp-projects@0.3.27-next.1 + - @backstage/plugin-github-actions@0.5.8-next.1 + - @backstage/plugin-gocd@0.1.14-next.1 + - @backstage/plugin-graphiql@0.2.40-next.1 + - @backstage/plugin-home@0.4.24-next.2 + - @backstage/plugin-jenkins@0.7.7-next.2 + - @backstage/plugin-kafka@0.3.8-next.1 + - @backstage/plugin-lighthouse@0.3.8-next.1 + - @backstage/plugin-newrelic@0.3.26-next.1 + - @backstage/plugin-newrelic-dashboard@0.2.1-next.1 + - @backstage/plugin-org@0.5.8-next.1 + - @backstage/plugin-pagerduty@0.5.1-next.1 + - @backstage/plugin-rollbar@0.4.8-next.1 + - @backstage/plugin-scaffolder@1.5.0-next.2 + - @backstage/plugin-search@1.0.1-next.1 + - @backstage/plugin-search-react@1.0.1-next.1 + - @backstage/plugin-sentry@0.4.1-next.1 + - @backstage/plugin-shortcuts@0.3.0-next.1 + - @backstage/plugin-stack-overflow@0.1.4-next.1 + - @backstage/plugin-tech-insights@0.2.4-next.1 + - @backstage/plugin-tech-radar@0.5.15-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.3-next.2 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + - @backstage/plugin-todo@0.2.10-next.1 + - @backstage/plugin-user-settings@0.4.7-next.1 + +## techdocs-cli-embedded-app@0.2.73-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.18.1-next.1 + - @backstage/plugin-techdocs@1.3.1-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/app-defaults@1.0.5-next.1 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-catalog@1.5.0-next.2 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + +## @internal/plugin-todo-list@1.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 diff --git a/docs/releases/v1.5.0-next.3-changelog.md b/docs/releases/v1.5.0-next.3-changelog.md new file mode 100644 index 0000000000..db9dc2ae48 --- /dev/null +++ b/docs/releases/v1.5.0-next.3-changelog.md @@ -0,0 +1,48 @@ +# Release v1.5.0-next.3 + +## @backstage/plugin-adr@0.2.0-next.2 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-adr-common@0.2.0-next.1 + +## @backstage/plugin-adr-backend@0.2.0-next.1 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-adr-common@0.2.0-next.1 + - @backstage/backend-common@0.15.0-next.2 + +## @backstage/plugin-adr-common@0.2.0-next.1 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +## @backstage/backend-common@0.15.0-next.2 + +### Patch Changes + +- 5e4dc173f7: Added a second validation to the `dir()` method of ZIP archive responses returned from `readTree()` that ensures that extracted files do not fall outside the target directory. + +## @backstage/create-app@0.4.30-next.3 + +### Patch Changes + +- Bumped create-app version. diff --git a/docs/releases/v1.5.0.md b/docs/releases/v1.5.0.md new file mode 100644 index 0000000000..ca4ae11185 --- /dev/null +++ b/docs/releases/v1.5.0.md @@ -0,0 +1,60 @@ +--- +id: v1.5.0 +title: v1.5.0 +description: Backstage Release v1.5.0 +--- + +These are the release notes for the v1.5.0 release of [Backstage](https://backstage.io/). + +A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done. + +## Highlights + +### GitHub Entity Provider + +Added a new `GitHubEntityProvider` ([documentation](https://backstage.io/docs/integrations/github/discovery)), which allows for automatic discovery of catalog entity definition files out of your GitHub projects. This is an improvement upon the `GithubDiscoveryProcessor` that existed before, and we recommend using entity providers rather than processors for discovery and ingestion when possible. Contributed by [@brentg-telus](https://github.com/brentg-telus) [#12822](https://github.com/backstage/backstage/pull/12822) + +### Experimental Plugin Reconfiguration + +This release adds an experimental API that allows plugin authors to define plugin wide options. These options can then be used by adopters of the plugin to reconfigure it to fit their app. Check out the [plugin customization](https://backstage.io/docs/plugins/customization) docs for more information on how to get started. Feedback is welcome on this new feature! Contributed by [@acierto](https://github.com/acierto) [#11404](https://github.com/backstage/backstage/pull/11404) + +### Experimental Backend System Evolution + +This release adds the new `@backstage/backend-defaults` package, part of the [evolution of the backend system](https://github.com/backstage/backstage/issues/11611). This package is highly experimental and we do not recommend using it for any purpose, yet. + +### New plugin: `@aws/aws-proton-plugin-for-backstage` + +Interact with AWS Proton in Backstage. Contributed by [@clareliguori](https://github.com/clareliguori) [#12193](https://github.com/backstage/backstage/pull/12193) + +### New plugin: `@backstage/plugin-github-issues` + +This new plugin can be used to display GitHub issues for your entities. Contributed by [@mrwolny](https://github.com/mrwolny) [#12875](https://github.com/backstage/backstage/pull/12875) + +### New plugin: `@backstage/plugin-sonarqube-backend` + +This new backend for `@backstage/plugin-sonarqube` replaces the Sonarqube proxy configuration; once it is installed, you can remove the `/sonarqube` proxy entry. For more information, see the plugin [README.md](https://github.com/backstage/backstage/blob/master/plugins/sonarqube-backend/README.md). Contributed by [@Neemys](https://github.com/Neemys) [#11925](https://github.com/backstage/backstage/pull/11925) + +### New module: `@backstage/plugin-catalog-backend-module-bitbucket-server` + +This new module for the catalog backend adds the `BitbucketServerEntityProvider`, which allows discovery of entities out of Bitbucket Server installations. Contributed by [@ONordander](https://github.com/ONordander) [#12835](https://github.com/backstage/backstage/pull/12835) + +## Security Fixes + +This release does not contain any security fixes. + +## Upgrade path + +We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated). + +## Links and References + +Below you can find a list of links and references to help you learn about and start using this new release. + +- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/) +- [GitHub repository](https://github.com/backstage/backstage) +- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy) +- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support +- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.5.0-changelog.md) +- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap) and [Plugins](https://backstage.io/plugins) + +Sign up for our [newsletter](https://mailchi.mp/spotify/backstage-community) if you want to be informed about what is happening in the world of Backstage. diff --git a/docs/tutorials/switching-sqlite-postgres.md b/docs/tutorials/switching-sqlite-postgres.md index c4e4bd83b6..c0c35999c6 100644 --- a/docs/tutorials/switching-sqlite-postgres.md +++ b/docs/tutorials/switching-sqlite-postgres.md @@ -86,3 +86,16 @@ backend: + # ca: # if you have a CA file and want to verify it you can uncomment this section + # $file: /ca/server.crt ``` + +### Using a single database + +By default, each plugin will get its own logical database, to ensure that there's no conflict in table names throughout the plugins that you install and to keep their concerns separate for other use cases further down the line. If you are limited in that you can only make use of a single database, you can use a special option `pluginDivisionMode` with `client: pg` in the config to create separate [PostgreSQL Schemas](https://www.postgresql.org/docs/current/ddl-schemas.html) instead of creating separate databases. + +You can enable this using the following config: + +```yaml +backend: + database: + client: pg + pluginDivisionMode: schema # defaults to database, but changing this to schema means plugins will be given their own schema (in the specified/default database) +``` diff --git a/microsite/blog/2022-07-19-releasing-backstage-search-1.0.md b/microsite/blog/2022-07-19-releasing-backstage-search-1.0.md new file mode 100644 index 0000000000..d1bff97a53 --- /dev/null +++ b/microsite/blog/2022-07-19-releasing-backstage-search-1.0.md @@ -0,0 +1,68 @@ +--- +# prettier-ignore +title: Releasing Backstage Search 1.0 +author: Emma Indal, Spotify +authorURL: https://www.linkedin.com/in/emma-indal +--- + +**TL;DR** If you’ve been waiting for Backstage Search to come out of beta, we’re excited to announce that [Backstage Search 1.0](https://backstage.io/docs/features/search/search-overview#backstage-search-10) is here! + +We first released the Backstage Search Platform over a year ago. Backstage Search Platform is a search experience built for you, by you. + +![Releasing Backstage Search 1.0](assets/22-07-19/releasing-backstage-search-v1.png) + +Backstage Search Platform makes it possible for you to search across your entire software ecosystem. With a Search platform that is customizable and extendable, you can identify your needs within your organization and set up search to solve these problems. Whether it is to search through the Software Catalog or technical documentation generated by the TechDocs plugin. + + + +## So what is Backstage Search 1.0? + +Since the first release of the Backstage Search Platform, we have seen a fantastic community grow around the search plugins. To mention just a few of these contributions: + +- More search engine modules: [Elasticsearch](https://www.npmjs.com/package/@backstage/plugin-search-backend-module-elasticsearch) originally [contributed](https://github.com/backstage/backstage/pull/6569) by Roadie and [Postgres](https://www.npmjs.com/package/@backstage/plugin-search-backend-module-pg) originally [contributed](https://github.com/backstage/backstage/pull/6682) by SDA SE +- More components: Quick search modal, originally [contributed](https://github.com/backstage/backstage/pull/7316) by Expedia Group +- More plugin integrations: TechDocs also [contributed](https://github.com/backstage/backstage/pull/6375) by Roadie and [Software Catalog](https://github.com/backstage/backstage/pull/4515) + +These are just a few contributions of the countless enhancements and improvements made by contributors across the globe. With a well adopted and tested search platform we feel confident to release Backstage Search as 1.0. + +Packages included in Backstage Search 1.0 release are: + +**Core search packages** + +- [@backstage/plugin-search](https://www.npmjs.com/package/@backstage/plugin-search) +- [@backstage/plugin-search-react](https://www.npmjs.com/package/@backstage/plugin-search-react) +- [@backstage/plugin-search-common](https://www.npmjs.com/package/@backstage/plugin-search-common) +- [@backstage/plugin-search-backend](https://www.npmjs.com/package/@backstage/plugin-search-backend) +- [@backstage/plugin-search-backend-node](https://www.npmjs.com/package/@backstage/plugin-search-backend-node) + +**Modules** + +- [@backstage/plugin-search-backend-module-elasticsearch](https://www.npmjs.com/package/@backstage/plugin-search-backend-module-elasticsearch) + +No additional features are released as part of the major release as the maintainers of the search packages focused on the following for this release: + +- Bug fixes and clean up of deprecations. +- Improved error handling for missing indices. +- Separation of AWS Elastic and Open Elastic support. +- Refactor the packages by moving reusable components from `@backstage/plugin-search` to `@backstage/plugin-search-react`. +- Improved documentation including tutorials for how to [Integrate Search into a plugin](https://backstage.io/docs/plugins/integrating-search-into-plugins). + +You might have noticed that the [@backstage/plugin-search-backend-module-pg](https://www.npmjs.com/package/@backstage/plugin-search-backend-module-pg) package is not part of 1.0. That’s because that package is a community supported module, and therefore we have not included it as part of 1.0. If you are interested in pushing the Postgres engine to 1.0, feel free to reach out to us in the [#search](https://discord.com/channels/687207715902193673/770283289327566848) channel on Discord. + +## Elasticsearch as the recommended engine for production usage + +When the Backstage Search Platform was first released, it came with an in-memory search engine as default - Lunr. While this is a good engine to use on a smaller scale and for local development (to avoid having to set up a search engine instance separately), it also has its limitations such as: + +- Lunr does not scale well. Horizontally scaled deployments of Backstage and/or Backstage Search backend using Lunr result in either duplicated indexing processes and indices or inconsistent index state across nodes. +- Lunr’s filter functionality is limited, especially for [logical AND/OR operators](https://github.com/olivernn/lunr.js/issues/353). +- Lunr has a smaller community than Elasticsearch, which could mean that adopters relying on it will have less by way of resources for iterating on and improving search. + +Therefore, we recommend using Elasticsearch for production usage. Moving forward, the search maintainers will prioritize the Elasticsearch engine while we’ll rely on the community to maintain the Postgres engine. + +## How to contribute + +If you want to contribute and to further improve search, you can check out the [open issues labeled with search](https://github.com/backstage/backstage/issues?q=is%3Aissue+search+label%3Asearch+is%3Aopen) or reach out to us at the [#search](https://discord.com/channels/687207715902193673/770283289327566848) Discord channel. + +## How to get started + +If you haven’t adopted the Backstage Search Platform yet and feel like now is a good time. Head over to the [getting started docs](https://backstage.io/docs/features/search/getting-started). diff --git a/microsite/blog/assets/22-07-19/releasing-backstage-search-v1.png b/microsite/blog/assets/22-07-19/releasing-backstage-search-v1.png new file mode 100644 index 0000000000..136e0c4084 Binary files /dev/null and b/microsite/blog/assets/22-07-19/releasing-backstage-search-v1.png differ diff --git a/microsite/data/on-demand/20220720-1.yaml b/microsite/data/on-demand/20220720-1.yaml index a1f51859f4..a7c0386a56 100644 --- a/microsite/data/on-demand/20220720-1.yaml +++ b/microsite/data/on-demand/20220720-1.yaml @@ -1,7 +1,7 @@ --- title: Adopters Community Sessions date: July 20, 2022 -category: Upcoming +category: Meetup description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc. youtubeUrl: https://youtu.be/4VFNlPxWcx8 youtubeImgUrl: https://backstage.io/img/b-sessions.png diff --git a/microsite/data/on-demand/20220727-1.yaml b/microsite/data/on-demand/20220727-1.yaml index 5f7712596f..b25b2e0789 100644 --- a/microsite/data/on-demand/20220727-1.yaml +++ b/microsite/data/on-demand/20220727-1.yaml @@ -1,9 +1,9 @@ --- title: Contributor Community Sessions date: July 27, 2022 -category: Upcoming +category: Meetup description: Join the maintainers and contributors for the Contributor Community Sessions -youtubeUrl: https://youtu.be/4VFNlPxWcx8 +youtubeUrl: https://youtu.be/pNLLrNN_hkE youtubeImgUrl: https://backstage.io/img/b-sessions.png rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com eventUrl: https://github.com/backstage/community/issues/52 diff --git a/microsite/data/on-demand/20220817-1.yaml b/microsite/data/on-demand/20220817-1.yaml new file mode 100644 index 0000000000..c0973656b4 --- /dev/null +++ b/microsite/data/on-demand/20220817-1.yaml @@ -0,0 +1,9 @@ +--- +title: Adopters Community Sessions +date: August 17, 2022 +category: Upcoming +description: Adopters Community Session ✨. It's the monthly meetup where we all come together to listen to the latest maintainer updates, learn from each other about adopting, share exciting new demos or discuss any relevant topic like developer effectiveness, developer experience, developer portals, etc. +youtubeUrl: https://youtu.be/qYnvc8ge1kg +youtubeImgUrl: https://backstage.io/img/b-sessions.png +rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com +eventUrl: https://github.com/backstage/community/issues/54 diff --git a/microsite/data/on-demand/20220824-1.yaml b/microsite/data/on-demand/20220824-1.yaml new file mode 100644 index 0000000000..411b87c74f --- /dev/null +++ b/microsite/data/on-demand/20220824-1.yaml @@ -0,0 +1,9 @@ +--- +title: Contributor Community Sessions +date: August 24, 2022 +category: Upcoming +description: Join the maintainers and contributors for the Contributor Community Sessions +youtubeUrl: https://youtu.be/qYnvc8ge1kg +youtubeImgUrl: https://backstage.io/img/b-sessions.png +rsvpUrl: https://calendar.google.com/calendar/embed?src=c_qup9gbhn9sqpuao6trttd8mk5s@group.calendar.google.com +eventUrl: https://github.com/backstage/community/issues/54 diff --git a/microsite/data/plugins/apollo-explorer.yaml b/microsite/data/plugins/apollo-explorer.yaml new file mode 100644 index 0000000000..068e26f0dc --- /dev/null +++ b/microsite/data/plugins/apollo-explorer.yaml @@ -0,0 +1,9 @@ +--- +title: Apollo Explorer +author: unredundant +authorUrl: https://github.com/unredundant +category: Debugging +description: Integrates Apollo Explorer graphs as a tool to browse GraphQL API endpoints inside Backstage. +documentation: https://github.com/backstage/backstage/blob/master/plugins/apollo-explorer/README.md +iconUrl: img/apollo-explorer.png +npmPackageName: '@backstage/plugin-apollo-explorer' diff --git a/microsite/data/plugins/backstage-plugin-api-linter b/microsite/data/plugins/backstage-plugin-api-linter new file mode 100644 index 0000000000..ae2a451ea7 --- /dev/null +++ b/microsite/data/plugins/backstage-plugin-api-linter @@ -0,0 +1,9 @@ +--- +title: backstage-plugin-api-linter +author: Zalando +authorUrl: https://github.com/zalando +category: Linting +description: API Linter is a quality assurance tool that checks the compliance of API's specifications to Zalando's API rules. +documentation: https://github.com/zalando/backstage-plugin-api-linter +iconUrl: https://raw.githubusercontent.com/zalando/zally/main/logo.png +npmPackageName: backstage-plugin-api-linter diff --git a/microsite/data/plugins/dynatrace.yaml b/microsite/data/plugins/dynatrace.yaml index 3ab85ae1eb..f204c4105c 100644 --- a/microsite/data/plugins/dynatrace.yaml +++ b/microsite/data/plugins/dynatrace.yaml @@ -3,7 +3,7 @@ title: Dynatrace author: TELUS authorUrl: https://github.com/telus category: Monitoring -description: View monitoring info from dynatrace for services in your software catalog. +description: View monitoring info from Dynatrace for services in your software catalog. documentation: https://github.com/backstage/backstage/tree/master/plugins/dynatrace iconUrl: img/dynatrace.svg npmPackageName: '@backstage/plugin-dynatrace' diff --git a/microsite/data/plugins/okta-entity-providers.yaml b/microsite/data/plugins/okta-entity-providers.yaml new file mode 100644 index 0000000000..93e4473fde --- /dev/null +++ b/microsite/data/plugins/okta-entity-providers.yaml @@ -0,0 +1,9 @@ +--- +title: Okta Organization Entity Provider +author: roadie.io +authorUrl: https://roadie.io/?utm_source=backstage.io&utm_medium=marketplace&utm_campaign=okta-entity-provider +category: Identity +description: Load users and groups from Okta into the Backstage catalog. +documentation: https://github.com/RoadieHQ/roadie-backstage-plugins/tree/main/plugins/backend/catalog-backend-module-okta +iconUrl: https://roadie.io/images/logos/okta.png +npmPackageName: '@roadiehq/catalog-backend-module-okta' diff --git a/microsite/data/plugins/tekton-pipelines.yaml b/microsite/data/plugins/tekton-pipelines.yaml new file mode 100644 index 0000000000..e53418037d --- /dev/null +++ b/microsite/data/plugins/tekton-pipelines.yaml @@ -0,0 +1,9 @@ +--- +title: Tekton Pipelines +author: JQuad Group +authorUrl: https://github.com/jquad-group +category: CI +description: View the status of the Tekton PipelineRun resources. +documentation: https://github.com/jquad-group/backstage-jquad#readme +iconUrl: https://raw.githubusercontent.com/jquad-group/backstage-jquad/main/img/tekton-horizontal-color.png +npmPackageName: '@jquad-group/plugin-tekton-pipelines' diff --git a/microsite/pages/en/live.js b/microsite/pages/en/live.js index f2ebd4bb1d..ee681a0835 100644 --- a/microsite/pages/en/live.js +++ b/microsite/pages/en/live.js @@ -34,7 +34,7 @@ const Background = props => { diff --git a/microsite/sidebars.json b/microsite/sidebars.json index 29fb3a0534..378d8085a3 100644 --- a/microsite/sidebars.json +++ b/microsite/sidebars.json @@ -1,6 +1,8 @@ { "releases": { "Release Notes": [ + "releases/v1.5.0", + "releases/v1.4.0", "releases/v1.3.0", "releases/v1.2.0", "releases/v1.1.0", @@ -149,10 +151,7 @@ { "type": "subcategory", "label": "Bitbucket", - "ids": [ - "integrations/bitbucket/locations", - "integrations/bitbucket/discovery" - ] + "ids": ["integrations/bitbucket/discovery"] }, { "type": "subcategory", @@ -162,6 +161,14 @@ "integrations/bitbucketCloud/discovery" ] }, + { + "type": "subcategory", + "label": "Bitbucket Server", + "ids": [ + "integrations/bitbucketServer/locations", + "integrations/bitbucketServer/discovery" + ] + }, { "type": "subcategory", "label": "Datadog", @@ -213,6 +220,7 @@ "plugins/integrating-plugin-into-software-catalog", "plugins/integrating-search-into-plugins", "plugins/composability", + "plugins/customization", "plugins/analytics", { "type": "subcategory", @@ -290,6 +298,7 @@ ], "Deployment": [ "deployment/index", + "deployment/scaling", "deployment/docker", "deployment/k8s", "deployment/heroku" diff --git a/microsite/siteConfig.js b/microsite/siteConfig.js index 8396a64729..68226b5681 100644 --- a/microsite/siteConfig.js +++ b/microsite/siteConfig.js @@ -39,7 +39,7 @@ const siteConfig = { fossWebsite: 'https://spotify.github.io/', // Google Analytics - gaTrackingId: 'UA-163836834-5', + gaTrackingId: 'G-KSEVGGNCJW', gaGtag: true, // For no header links in the top nav bar -> headerLinks: [], diff --git a/microsite/static/img/apollo-explorer.png b/microsite/static/img/apollo-explorer.png new file mode 100644 index 0000000000..322c003803 Binary files /dev/null and b/microsite/static/img/apollo-explorer.png differ diff --git a/mkdocs.yml b/mkdocs.yml index 04d62d32d4..bf577e53a1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -95,11 +95,13 @@ nav: - Discovery: 'integrations/azure/discovery.md' - Org Data: 'integrations/azure/org.md' - Bitbucket: - - Locations: 'integrations/bitbucket/locations.md' - Discovery: 'integrations/bitbucket/discovery.md' - Bitbucket Cloud: - Locations: 'integrations/bitbucketCloud/locations.md' - Discovery: 'integrations/bitbucketCloud/discovery.md' + - Bitbucket Server: + - Locations: 'integrations/bitbucketServer/locations.md' + - Discovery: 'integrations/bitbucketServer/discovery.md' - Datadog: - Installation: 'integrations/datadog-rum/installation.md' - Gerrit: @@ -164,6 +166,7 @@ nav: - Glossary: 'auth/glossary.md' - Deployment: - Deploying Backstage: 'deployment/index.md' + - Scaling: 'deployment/scaling.md' - Docker: 'deployment/docker.md' - Kubernetes: 'deployment/k8s.md' - Heroku: 'deployment/heroku.md' diff --git a/package.json b/package.json index 680c668fe6..3fcb63aa86 100644 --- a/package.json +++ b/package.json @@ -45,11 +45,10 @@ ] }, "resolutions": { - "**/@graphql-codegen/cli/**/ws": "^8.0.0", "@types/react": "^17", "@types/react-dom": "^17" }, - "version": "1.4.0-next.3", + "version": "1.5.0", "dependencies": { "@manypkg/get-packages": "^1.1.3", "@microsoft/api-documenter": "^7.17.11", @@ -69,7 +68,7 @@ "eslint-plugin-notice": "^0.9.10", "fs-extra": "10.1.0", "husky": "^8.0.0", - "lerna": "^5.0.0", + "lerna": "~5.0.0", "lint-staged": "^13.0.0", "minimist": "^1.2.5", "prettier": "^2.2.1", diff --git a/packages/app-defaults/CHANGELOG.md b/packages/app-defaults/CHANGELOG.md index 8e50e13300..77949cbb27 100644 --- a/packages/app-defaults/CHANGELOG.md +++ b/packages/app-defaults/CHANGELOG.md @@ -1,5 +1,44 @@ # @backstage/app-defaults +## 1.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/core-app-api@1.0.5 + - @backstage/plugin-permission-react@0.4.4 + +## 1.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-permission-react@0.4.4-next.0 + +## 1.0.4 + +### Patch Changes + +- 881fc75a75: Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/plugin-permission-react@0.4.3 + ## 1.0.4-next.3 ### Patch Changes diff --git a/packages/app-defaults/package.json b/packages/app-defaults/package.json index 17c196da79..04852ec4b5 100644 --- a/packages/app-defaults/package.json +++ b/packages/app-defaults/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/app-defaults", "description": "Provides the default wiring of a Backstage App", - "version": "1.0.4-next.3", + "version": "1.0.5", "private": false, "publishConfig": { "access": "public", @@ -33,11 +33,11 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-permission-react": "^0.4.3-next.1", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-app-api": "^1.0.5", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-permission-react": "^0.4.4", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "react-router-dom": "6.0.0-beta.0" @@ -46,8 +46,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@types/jest": "^26.0.7", diff --git a/packages/app/CHANGELOG.md b/packages/app/CHANGELOG.md index 65e4a5bc85..cdc3283c1f 100644 --- a/packages/app/CHANGELOG.md +++ b/packages/app/CHANGELOG.md @@ -1,5 +1,247 @@ # example-app +## 0.2.74 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes@0.7.1 + - @backstage/cli@0.18.1 + - @backstage/plugin-techdocs@1.3.1 + - @backstage/plugin-home@0.4.24 + - @backstage/core-components@0.11.0 + - @backstage/plugin-scaffolder@1.5.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-cost-insights@0.11.30 + - @backstage/plugin-graphiql@0.2.40 + - @backstage/plugin-catalog-common@1.0.5 + - @backstage/plugin-kafka@0.3.8 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.3 + - @backstage/plugin-gocd@0.1.14 + - @backstage/plugin-sentry@0.4.1 + - @backstage/plugin-api-docs@0.8.8 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/plugin-shortcuts@0.3.0 + - @backstage/plugin-tech-radar@0.5.15 + - @backstage/app-defaults@1.0.5 + - @backstage/core-app-api@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-airbrake@0.3.8 + - @backstage/plugin-apache-airflow@0.2.1 + - @backstage/plugin-azure-devops@0.1.24 + - @backstage/plugin-badges@0.2.32 + - @internal/plugin-catalog-customized@0.0.1 + - @backstage/plugin-catalog-graph@0.2.20 + - @backstage/plugin-catalog-import@0.8.11 + - @backstage/plugin-circleci@0.3.8 + - @backstage/plugin-cloudbuild@0.3.8 + - @backstage/plugin-code-coverage@0.2.1 + - @backstage/plugin-dynatrace@0.1.2 + - @backstage/plugin-explore@0.3.39 + - @backstage/plugin-gcalendar@0.3.4 + - @backstage/plugin-gcp-projects@0.3.27 + - @backstage/plugin-github-actions@0.5.8 + - @backstage/plugin-jenkins@0.7.7 + - @backstage/plugin-lighthouse@0.3.8 + - @backstage/plugin-newrelic@0.3.26 + - @backstage/plugin-newrelic-dashboard@0.2.1 + - @backstage/plugin-org@0.5.8 + - @backstage/plugin-pagerduty@0.5.1 + - @backstage/plugin-permission-react@0.4.4 + - @backstage/plugin-rollbar@0.4.8 + - @backstage/plugin-search@1.0.1 + - @backstage/plugin-search-react@1.0.1 + - @backstage/plugin-stack-overflow@0.1.4 + - @backstage/plugin-tech-insights@0.2.4 + - @backstage/plugin-todo@0.2.10 + - @backstage/plugin-user-settings@0.4.7 + +## 0.2.74-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes@0.7.1-next.2 + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/plugin-cost-insights@0.11.30-next.1 + - @backstage/cli@0.18.1-next.1 + - @backstage/plugin-techdocs@1.3.1-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/app-defaults@1.0.5-next.1 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-airbrake@0.3.8-next.1 + - @backstage/plugin-apache-airflow@0.2.1-next.1 + - @backstage/plugin-api-docs@0.8.8-next.2 + - @backstage/plugin-azure-devops@0.1.24-next.1 + - @backstage/plugin-badges@0.2.32-next.1 + - @backstage/plugin-catalog-graph@0.2.20-next.1 + - @backstage/plugin-catalog-import@0.8.11-next.1 + - @backstage/plugin-circleci@0.3.8-next.1 + - @backstage/plugin-cloudbuild@0.3.8-next.1 + - @backstage/plugin-code-coverage@0.2.1-next.1 + - @backstage/plugin-dynatrace@0.1.2-next.1 + - @backstage/plugin-explore@0.3.39-next.1 + - @backstage/plugin-gcalendar@0.3.4-next.1 + - @backstage/plugin-gcp-projects@0.3.27-next.1 + - @backstage/plugin-github-actions@0.5.8-next.1 + - @backstage/plugin-gocd@0.1.14-next.1 + - @backstage/plugin-graphiql@0.2.40-next.1 + - @backstage/plugin-home@0.4.24-next.2 + - @backstage/plugin-jenkins@0.7.7-next.2 + - @backstage/plugin-kafka@0.3.8-next.1 + - @backstage/plugin-lighthouse@0.3.8-next.1 + - @backstage/plugin-newrelic@0.3.26-next.1 + - @backstage/plugin-newrelic-dashboard@0.2.1-next.1 + - @backstage/plugin-org@0.5.8-next.1 + - @backstage/plugin-pagerduty@0.5.1-next.1 + - @backstage/plugin-rollbar@0.4.8-next.1 + - @backstage/plugin-scaffolder@1.5.0-next.2 + - @backstage/plugin-search@1.0.1-next.1 + - @backstage/plugin-search-react@1.0.1-next.1 + - @backstage/plugin-sentry@0.4.1-next.1 + - @backstage/plugin-shortcuts@0.3.0-next.1 + - @backstage/plugin-stack-overflow@0.1.4-next.1 + - @backstage/plugin-tech-insights@0.2.4-next.1 + - @backstage/plugin-tech-radar@0.5.15-next.1 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.3-next.2 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + - @backstage/plugin-todo@0.2.10-next.1 + - @backstage/plugin-user-settings@0.4.7-next.1 + +## 0.2.74-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-kubernetes@0.7.1-next.1 + - @backstage/plugin-home@0.4.24-next.1 + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-scaffolder@1.5.0-next.1 + - @backstage/plugin-techdocs@1.3.1-next.1 + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.3-next.1 + - @backstage/plugin-api-docs@0.8.8-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + - @backstage/plugin-jenkins@0.7.7-next.1 + +## 0.2.74-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-techdocs@1.3.1-next.0 + - @backstage/cli@0.18.1-next.0 + - @backstage/plugin-kafka@0.3.8-next.0 + - @backstage/plugin-gocd@0.1.14-next.0 + - @backstage/plugin-sentry@0.4.1-next.0 + - @backstage/plugin-shortcuts@0.3.0-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-import@0.8.11-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/plugin-github-actions@0.5.8-next.0 + - @backstage/plugin-scaffolder@1.4.1-next.0 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.3-next.0 + - @backstage/app-defaults@1.0.5-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-airbrake@0.3.8-next.0 + - @backstage/plugin-apache-airflow@0.2.1-next.0 + - @backstage/plugin-api-docs@0.8.8-next.0 + - @backstage/plugin-azure-devops@0.1.24-next.0 + - @backstage/plugin-badges@0.2.32-next.0 + - @backstage/plugin-catalog-graph@0.2.20-next.0 + - @backstage/plugin-circleci@0.3.8-next.0 + - @backstage/plugin-cloudbuild@0.3.8-next.0 + - @backstage/plugin-code-coverage@0.2.1-next.0 + - @backstage/plugin-cost-insights@0.11.30-next.0 + - @backstage/plugin-dynatrace@0.1.2-next.0 + - @backstage/plugin-explore@0.3.39-next.0 + - @backstage/plugin-gcalendar@0.3.4-next.0 + - @backstage/plugin-gcp-projects@0.3.27-next.0 + - @backstage/plugin-graphiql@0.2.40-next.0 + - @backstage/plugin-home@0.4.24-next.0 + - @backstage/plugin-jenkins@0.7.7-next.0 + - @backstage/plugin-kubernetes@0.7.1-next.0 + - @backstage/plugin-lighthouse@0.3.8-next.0 + - @backstage/plugin-newrelic@0.3.26-next.0 + - @backstage/plugin-newrelic-dashboard@0.2.1-next.0 + - @backstage/plugin-org@0.5.8-next.0 + - @backstage/plugin-pagerduty@0.5.1-next.0 + - @backstage/plugin-permission-react@0.4.4-next.0 + - @backstage/plugin-rollbar@0.4.8-next.0 + - @backstage/plugin-search@1.0.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + - @backstage/plugin-stack-overflow@0.1.4-next.0 + - @backstage/plugin-tech-insights@0.2.4-next.0 + - @backstage/plugin-tech-radar@0.5.15-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + - @backstage/plugin-todo@0.2.10-next.0 + - @backstage/plugin-user-settings@0.4.7-next.0 + - @internal/plugin-catalog-customized@0.0.1-next.0 + +## 0.2.73 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-cost-insights@0.11.29 + - @backstage/plugin-code-coverage@0.2.0 + - @backstage/plugin-scaffolder@1.4.0 + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/plugin-search@1.0.0 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/plugin-kubernetes@0.7.0 + - @backstage/plugin-tech-radar@0.5.14 + - @backstage/plugin-catalog@1.4.0 + - @backstage/plugin-newrelic-dashboard@0.2.0 + - @backstage/cli@0.18.0 + - @backstage/plugin-apache-airflow@0.2.0 + - @backstage/app-defaults@1.0.4 + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-jenkins@0.7.6 + - @backstage/plugin-stack-overflow@0.1.3 + - @backstage/plugin-catalog-import@0.8.10 + - @backstage/plugin-github-actions@0.5.7 + - @backstage/plugin-sentry@0.4.0 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-airbrake@0.3.7 + - @backstage/plugin-api-docs@0.8.7 + - @backstage/plugin-azure-devops@0.1.23 + - @backstage/plugin-badges@0.2.31 + - @backstage/plugin-circleci@0.3.7 + - @backstage/plugin-cloudbuild@0.3.7 + - @backstage/plugin-dynatrace@0.1.1 + - @backstage/plugin-explore@0.3.38 + - @backstage/plugin-gcalendar@0.3.3 + - @backstage/plugin-gcp-projects@0.3.26 + - @backstage/plugin-gocd@0.1.13 + - @backstage/plugin-graphiql@0.2.39 + - @backstage/plugin-home@0.4.23 + - @backstage/plugin-kafka@0.3.7 + - @backstage/plugin-lighthouse@0.3.7 + - @backstage/plugin-newrelic@0.3.25 + - @backstage/plugin-org@0.5.7 + - @backstage/plugin-pagerduty@0.5.0 + - @backstage/plugin-rollbar@0.4.7 + - @backstage/plugin-shortcuts@0.2.8 + - @backstage/plugin-tech-insights@0.2.3 + - @backstage/plugin-techdocs-module-addons-contrib@1.0.2 + - @backstage/plugin-techdocs@1.3.0 + - @backstage/plugin-todo@0.2.9 + - @backstage/plugin-user-settings@0.4.6 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/plugin-catalog-common@1.0.4 + - @backstage/plugin-catalog-graph@0.2.19 + - @backstage/plugin-permission-react@0.4.3 + ## 0.2.73-next.3 ### Patch Changes diff --git a/packages/app/package.json b/packages/app/package.json index 08833ca1a3..d4e0644f3a 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,67 +1,66 @@ { "name": "example-app", - "version": "0.2.73-next.3", + "version": "0.2.74", "private": true, "backstage": { "role": "frontend" }, "bundled": true, "dependencies": { - "@backstage/app-defaults": "^1.0.4-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/app-defaults": "^1.0.5", + "@backstage/catalog-model": "^1.1.0", + "@backstage/cli": "^0.18.1", "@backstage/config": "^1.0.1", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/integration-react": "^1.1.2-next.3", - "@backstage/plugin-airbrake": "^0.3.7-next.3", - "@backstage/plugin-api-docs": "^0.8.7-next.3", - "@backstage/plugin-azure-devops": "^0.1.23-next.3", - "@backstage/plugin-apache-airflow": "^0.2.0-next.3", - "@backstage/plugin-badges": "^0.2.31-next.3", - "@backstage/plugin-catalog": "^1.4.0-next.3", - "@backstage/plugin-catalog-common": "^1.0.4-next.0", - "@backstage/plugin-catalog-graph": "^0.2.19-next.3", - "@backstage/plugin-catalog-import": "^0.8.10-next.3", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/plugin-circleci": "^0.3.7-next.3", - "@backstage/plugin-cloudbuild": "^0.3.7-next.3", - "@backstage/plugin-code-coverage": "^0.2.0-next.3", - "@backstage/plugin-cost-insights": "^0.11.29-next.3", - "@backstage/plugin-dynatrace": "^0.1.1-next.3", - "@backstage/plugin-explore": "^0.3.38-next.3", - "@backstage/plugin-gcalendar": "^0.3.3-next.3", - "@backstage/plugin-gcp-projects": "^0.3.26-next.3", - "@backstage/plugin-github-actions": "^0.5.7-next.3", - "@backstage/plugin-gocd": "^0.1.13-next.3", - "@backstage/plugin-graphiql": "^0.2.39-next.3", - "@backstage/plugin-home": "^0.4.23-next.3", - "@backstage/plugin-jenkins": "^0.7.6-next.3", - "@backstage/plugin-kafka": "^0.3.7-next.3", - "@backstage/plugin-kubernetes": "^0.7.0-next.3", - "@backstage/plugin-lighthouse": "^0.3.7-next.3", - "@backstage/plugin-newrelic": "^0.3.25-next.3", - "@backstage/plugin-newrelic-dashboard": "^0.2.0-next.3", - "@backstage/plugin-org": "^0.5.7-next.3", - "@backstage/plugin-pagerduty": "0.5.0-next.3", - "@backstage/plugin-permission-react": "^0.4.3-next.1", - "@backstage/plugin-rollbar": "^0.4.7-next.3", - "@backstage/plugin-scaffolder": "^1.4.0-next.3", - "@backstage/plugin-search": "^0.9.1-next.3", - "@backstage/plugin-search-react": "^0.2.2-next.3", - "@backstage/plugin-search-common": "^0.3.6-next.0", - "@backstage/plugin-sentry": "^0.4.0-next.3", - "@backstage/plugin-shortcuts": "^0.2.8-next.3", - "@backstage/plugin-stack-overflow": "^0.1.3-next.3", - "@backstage/plugin-tech-radar": "^0.5.14-next.3", - "@backstage/plugin-techdocs": "^1.2.1-next.3", - "@backstage/plugin-techdocs-react": "^1.0.2-next.2", - "@backstage/plugin-techdocs-module-addons-contrib": "^1.0.2-next.3", - "@backstage/plugin-todo": "^0.2.9-next.3", - "@backstage/plugin-user-settings": "^0.4.6-next.3", - "@backstage/plugin-tech-insights": "^0.2.3-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/integration-react": "^1.1.3", + "@backstage/plugin-airbrake": "^0.3.8", + "@backstage/plugin-api-docs": "^0.8.8", + "@backstage/plugin-azure-devops": "^0.1.24", + "@backstage/plugin-apache-airflow": "^0.2.1", + "@backstage/plugin-badges": "^0.2.32", + "@backstage/plugin-catalog-common": "^1.0.5", + "@backstage/plugin-catalog-graph": "^0.2.20", + "@backstage/plugin-catalog-import": "^0.8.11", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/plugin-circleci": "^0.3.8", + "@backstage/plugin-cloudbuild": "^0.3.8", + "@backstage/plugin-code-coverage": "^0.2.1", + "@backstage/plugin-cost-insights": "^0.11.30", + "@backstage/plugin-dynatrace": "^0.1.2", + "@backstage/plugin-explore": "^0.3.39", + "@backstage/plugin-gcalendar": "^0.3.4", + "@backstage/plugin-gcp-projects": "^0.3.27", + "@backstage/plugin-github-actions": "^0.5.8", + "@backstage/plugin-gocd": "^0.1.14", + "@backstage/plugin-graphiql": "^0.2.40", + "@backstage/plugin-home": "^0.4.24", + "@backstage/plugin-jenkins": "^0.7.7", + "@backstage/plugin-kafka": "^0.3.8", + "@backstage/plugin-kubernetes": "^0.7.1", + "@backstage/plugin-lighthouse": "^0.3.8", + "@backstage/plugin-newrelic": "^0.3.26", + "@backstage/plugin-newrelic-dashboard": "^0.2.1", + "@backstage/plugin-org": "^0.5.8", + "@backstage/plugin-pagerduty": "0.5.1", + "@backstage/plugin-permission-react": "^0.4.4", + "@backstage/plugin-rollbar": "^0.4.8", + "@backstage/plugin-scaffolder": "^1.5.0", + "@backstage/plugin-search": "^1.0.1", + "@backstage/plugin-search-common": "^1.0.0", + "@backstage/plugin-search-react": "^1.0.1", + "@backstage/plugin-sentry": "^0.4.1", + "@backstage/plugin-shortcuts": "^0.3.0", + "@backstage/plugin-stack-overflow": "^0.1.4", + "@backstage/plugin-tech-insights": "^0.2.4", + "@backstage/plugin-tech-radar": "^0.5.15", + "@backstage/plugin-techdocs": "^1.3.1", + "@backstage/plugin-techdocs-module-addons-contrib": "^1.0.3", + "@backstage/plugin-techdocs-react": "^1.0.3", + "@backstage/plugin-todo": "^0.2.10", + "@backstage/plugin-user-settings": "^0.4.7", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -70,6 +69,7 @@ "@roadiehq/backstage-plugin-github-insights": "^2.0.0", "@roadiehq/backstage-plugin-github-pull-requests": "^2.0.0", "@roadiehq/backstage-plugin-travis-ci": "^2.0.0", + "@internal/plugin-catalog-customized": "0.0.1", "history": "^5.0.0", "prop-types": "^15.7.2", "react": "^17.0.2", @@ -81,7 +81,7 @@ "zen-observable": "^0.8.15" }, "devDependencies": { - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/test-utils": "^1.1.3", "@rjsf/core": "^3.2.1", "@testing-library/cypress": "^8.0.2", "@testing-library/jest-dom": "^5.10.1", diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index 35c61f2f16..a0390d96e8 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -35,11 +35,13 @@ import { } from '@backstage/core-components'; import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs'; import { AzurePullRequestsPage } from '@backstage/plugin-azure-devops'; + import { CatalogEntityPage, CatalogIndexPage, catalogPlugin, -} from '@backstage/plugin-catalog'; +} from '@internal/plugin-catalog-customized'; + import { CatalogGraphPage } from '@backstage/plugin-catalog-graph'; import { CatalogImportPage, @@ -60,6 +62,7 @@ import { NewRelicPage } from '@backstage/plugin-newrelic'; import { ScaffolderFieldExtensions, ScaffolderPage, + NextScaffolderPage, scaffolderPlugin, } from '@backstage/plugin-scaffolder'; import { SearchPage } from '@backstage/plugin-search'; @@ -88,7 +91,10 @@ import { apis } from './apis'; import { entityPage } from './components/catalog/EntityPage'; import { homePage } from './components/home/HomePage'; import { Root } from './components/Root'; -import { LowerCaseValuePickerFieldExtension } from './components/scaffolder/customScaffolderExtensions'; +import { + DelayingComponentFieldExtension, + LowerCaseValuePickerFieldExtension, +} from './components/scaffolder/customScaffolderExtensions'; import { defaultPreviewTemplate } from './components/scaffolder/defaultPreviewTemplate'; import { searchPage } from './components/search/SearchPage'; import { providers } from './identityProviders'; @@ -210,6 +216,24 @@ const routes = ( + + entity?.metadata?.tags?.includes('recommended') ?? false, + }, + ]} + /> + } + > + + + + } /> , +) => { + const { onChange, formData, rawErrors } = props; + return ( + onChange({ test: value })} + margin="normal" + error={rawErrors?.length > 0 && !formData} + /> + ); +}; + +export const DelayingComponentFieldExtension = scaffolderPlugin.provide( + createScaffolderFieldExtension({ + name: 'DelayingComponent', + component: MockDelayComponent, + validation: async ( + value: { test?: string }, + validation: FieldValidation, + ) => { + // delay 2 seconds + await new Promise(resolve => setTimeout(resolve, 2000)); + + if (value.test !== 'pass') { + validation.addError('value was not equal to pass'); + } + }, + }), +); diff --git a/packages/app/src/components/search/SearchModal.tsx b/packages/app/src/components/search/SearchModal.tsx index 99fc964cb2..218ead9b82 100644 --- a/packages/app/src/components/search/SearchModal.tsx +++ b/packages/app/src/components/search/SearchModal.tsx @@ -33,7 +33,7 @@ import { useContent, } from '@backstage/core-components'; import { useApi, useRouteRef } from '@backstage/core-plugin-api'; -import { CatalogSearchResultListItem } from '@backstage/plugin-catalog'; +import { CatalogSearchResultListItem } from '@internal/plugin-catalog-customized'; import { catalogApiRef, CATALOG_FILTER_EXISTS, diff --git a/packages/app/src/components/search/SearchPage.tsx b/packages/app/src/components/search/SearchPage.tsx index 053fa81da8..99814130c2 100644 --- a/packages/app/src/components/search/SearchPage.tsx +++ b/packages/app/src/components/search/SearchPage.tsx @@ -24,7 +24,7 @@ import { useSidebarPinState, } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; -import { CatalogSearchResultListItem } from '@backstage/plugin-catalog'; +import { CatalogSearchResultListItem } from '@internal/plugin-catalog-customized'; import { catalogApiRef, CATALOG_FILTER_EXISTS, diff --git a/packages/backend-app-api/CHANGELOG.md b/packages/backend-app-api/CHANGELOG.md index 334de3b4d8..a467ef5b7a 100644 --- a/packages/backend-app-api/CHANGELOG.md +++ b/packages/backend-app-api/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/backend-app-api +## 0.2.0 + +### Minor Changes + +- 5df230d48c: Introduced a new `backend-defaults` package carrying `createBackend` which was previously exported from `backend-app-api`. + The `backend-app-api` package now exports the `createSpecializedBacked` that does not add any service factories by default. + +### Patch Changes + +- 0599732ec0: Refactored experimental backend system with new type names. +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-plugin-api@0.1.1 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-permission-node@0.6.4 + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/backend-plugin-api@0.1.1-next.0 + - @backstage/plugin-permission-node@0.6.4-next.0 + +## 0.1.0 + +### Minor Changes + +- 91c1d12123: Add initial plumbing for creating backends using the experimental backend framework. + + This package is highly **EXPERIMENTAL** and should not be used in production. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.0 + - @backstage/backend-common@0.14.1 + - @backstage/plugin-permission-node@0.6.3 + - @backstage/backend-tasks@0.3.3 + ## 0.1.0-next.0 ### Minor Changes diff --git a/packages/backend-app-api/api-report.md b/packages/backend-app-api/api-report.md index a37ec6abc6..0f8806870d 100644 --- a/packages/backend-app-api/api-report.md +++ b/packages/backend-app-api/api-report.md @@ -3,23 +3,75 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -import { AnyServiceFactory } from '@backstage/backend-plugin-api'; -import { BackendRegistrable } from '@backstage/backend-plugin-api'; +import { BackendFeature } from '@backstage/backend-plugin-api'; +import { Config } from '@backstage/config'; +import { ExtensionPoint } from '@backstage/backend-plugin-api'; +import { HttpRouterService } from '@backstage/backend-plugin-api'; +import { Logger } from '@backstage/backend-plugin-api'; +import { PermissionAuthorizer } from '@backstage/plugin-permission-common'; +import { PermissionEvaluator } from '@backstage/plugin-permission-common'; +import { PluginCacheManager } from '@backstage/backend-common'; +import { PluginDatabaseManager } from '@backstage/backend-common'; +import { PluginEndpointDiscovery } from '@backstage/backend-common'; +import { PluginTaskScheduler } from '@backstage/backend-tasks'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceRef } from '@backstage/backend-plugin-api'; +import { TokenManager } from '@backstage/backend-common'; +import { UrlReader } from '@backstage/backend-common'; // @public (undocumented) export interface Backend { // (undocumented) - add(extension: BackendRegistrable): void; + add(feature: BackendFeature): void; // (undocumented) start(): Promise; } // @public (undocumented) -export function createBackend(options?: CreateBackendOptions): Backend; +export const cacheFactory: ServiceFactory; // @public (undocumented) -export interface CreateBackendOptions { +export const configFactory: ServiceFactory; + +// @public (undocumented) +export function createSpecializedBackend( + options: CreateSpecializedBackendOptions, +): Backend; + +// @public (undocumented) +export interface CreateSpecializedBackendOptions { // (undocumented) - apis: AnyServiceFactory[]; + services: ServiceFactory[]; } + +// @public (undocumented) +export const databaseFactory: ServiceFactory; + +// @public (undocumented) +export const discoveryFactory: ServiceFactory; + +// @public (undocumented) +export const httpRouterFactory: ServiceFactory; + +// @public (undocumented) +export const loggerFactory: ServiceFactory; + +// @public (undocumented) +export const permissionsFactory: ServiceFactory< + PermissionAuthorizer | PermissionEvaluator +>; + +// @public (undocumented) +export const schedulerFactory: ServiceFactory; + +// @public (undocumented) +export type ServiceOrExtensionPoint = + | ExtensionPoint + | ServiceRef; + +// @public (undocumented) +export const tokenManagerFactory: ServiceFactory; + +// @public (undocumented) +export const urlReaderFactory: ServiceFactory; ``` diff --git a/packages/backend-app-api/package.json b/packages/backend-app-api/package.json index f49fe159f3..fc908d107b 100644 --- a/packages/backend-app-api/package.json +++ b/packages/backend-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-app-api", "description": "Core API used by Backstage backend apps", - "version": "0.1.0-next.0", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -34,16 +34,16 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-plugin-api": "^0.1.0-next.0", - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/backend-tasks": "^0.3.3-next.3", - "@backstage/plugin-permission-node": "^0.6.3-next.2", + "@backstage/backend-plugin-api": "^0.1.1", + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-tasks": "^0.3.4", + "@backstage/plugin-permission-node": "^0.6.4", "express": "^4.17.1", "express-promise-router": "^4.1.0", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3" + "@backstage/cli": "^0.18.1" }, "files": [ "dist", diff --git a/packages/backend-app-api/src/index.ts b/packages/backend-app-api/src/index.ts index c58379c3e4..02633f3732 100644 --- a/packages/backend-app-api/src/index.ts +++ b/packages/backend-app-api/src/index.ts @@ -21,3 +21,4 @@ */ export * from './wiring'; +export * from './services/implementations'; diff --git a/packages/backend-app-api/src/services/implementations/cacheService.ts b/packages/backend-app-api/src/services/implementations/cacheService.ts index 034f85f917..c5e58b4a41 100644 --- a/packages/backend-app-api/src/services/implementations/cacheService.ts +++ b/packages/backend-app-api/src/services/implementations/cacheService.ts @@ -21,7 +21,7 @@ import { cacheServiceRef, } from '@backstage/backend-plugin-api'; -// TODO: Work out some naming and implementation patterns for these +/** @public */ export const cacheFactory = createServiceFactory({ service: cacheServiceRef, deps: { diff --git a/packages/backend-app-api/src/services/implementations/configService.ts b/packages/backend-app-api/src/services/implementations/configService.ts index 94a59baf34..c4aa641f72 100644 --- a/packages/backend-app-api/src/services/implementations/configService.ts +++ b/packages/backend-app-api/src/services/implementations/configService.ts @@ -22,6 +22,7 @@ import { loggerServiceRef, } from '@backstage/backend-plugin-api'; +/** @public */ export const configFactory = createServiceFactory({ service: configServiceRef, deps: { diff --git a/packages/backend-app-api/src/services/implementations/databaseService.ts b/packages/backend-app-api/src/services/implementations/databaseService.ts index a52da1e444..b2bc19de84 100644 --- a/packages/backend-app-api/src/services/implementations/databaseService.ts +++ b/packages/backend-app-api/src/services/implementations/databaseService.ts @@ -21,6 +21,7 @@ import { databaseServiceRef, } from '@backstage/backend-plugin-api'; +/** @public */ export const databaseFactory = createServiceFactory({ service: databaseServiceRef, deps: { diff --git a/packages/backend-app-api/src/services/implementations/discoveryService.ts b/packages/backend-app-api/src/services/implementations/discoveryService.ts index 23af1924a0..3f1a584c61 100644 --- a/packages/backend-app-api/src/services/implementations/discoveryService.ts +++ b/packages/backend-app-api/src/services/implementations/discoveryService.ts @@ -21,6 +21,7 @@ import { discoveryServiceRef, } from '@backstage/backend-plugin-api'; +/** @public */ export const discoveryFactory = createServiceFactory({ service: discoveryServiceRef, deps: { diff --git a/packages/backend-app-api/src/services/implementations/httpRouterService.ts b/packages/backend-app-api/src/services/implementations/httpRouterService.ts index 1f72378643..6460a77eaf 100644 --- a/packages/backend-app-api/src/services/implementations/httpRouterService.ts +++ b/packages/backend-app-api/src/services/implementations/httpRouterService.ts @@ -23,6 +23,7 @@ import Router from 'express-promise-router'; import { Handler } from 'express'; import { createServiceBuilder } from '@backstage/backend-common'; +/** @public */ export const httpRouterFactory = createServiceFactory({ service: httpRouterServiceRef, deps: { diff --git a/packages/backend-app-api/src/services/implementations/index.ts b/packages/backend-app-api/src/services/implementations/index.ts index e6b6604069..048c952b4e 100644 --- a/packages/backend-app-api/src/services/implementations/index.ts +++ b/packages/backend-app-api/src/services/implementations/index.ts @@ -14,26 +14,13 @@ * limitations under the License. */ -import { cacheFactory } from './cacheService'; -import { configFactory } from './configService'; -import { databaseFactory } from './databaseService'; -import { discoveryFactory } from './discoveryService'; -import { loggerFactory } from './loggerService'; -import { permissionsFactory } from './permissionsService'; -import { schedulerFactory } from './schedulerService'; -import { tokenManagerFactory } from './tokenManagerService'; -import { urlReaderFactory } from './urlReaderService'; -import { httpRouterFactory } from './httpRouterService'; - -export const defaultServiceFactories = [ - cacheFactory, - configFactory, - databaseFactory, - discoveryFactory, - loggerFactory, - permissionsFactory, - schedulerFactory, - tokenManagerFactory, - urlReaderFactory, - httpRouterFactory, -]; +export { cacheFactory } from './cacheService'; +export { configFactory } from './configService'; +export { databaseFactory } from './databaseService'; +export { discoveryFactory } from './discoveryService'; +export { loggerFactory } from './loggerService'; +export { permissionsFactory } from './permissionsService'; +export { schedulerFactory } from './schedulerService'; +export { tokenManagerFactory } from './tokenManagerService'; +export { urlReaderFactory } from './urlReaderService'; +export { httpRouterFactory } from './httpRouterService'; diff --git a/packages/backend-app-api/src/services/implementations/loggerService.ts b/packages/backend-app-api/src/services/implementations/loggerService.ts index fbeb4b9ade..e90b591302 100644 --- a/packages/backend-app-api/src/services/implementations/loggerService.ts +++ b/packages/backend-app-api/src/services/implementations/loggerService.ts @@ -38,6 +38,7 @@ class BackstageLogger implements Logger { } } +/** @public */ export const loggerFactory = createServiceFactory({ service: loggerServiceRef, deps: {}, diff --git a/packages/backend-app-api/src/services/implementations/permissionsService.ts b/packages/backend-app-api/src/services/implementations/permissionsService.ts index 97f0330917..26fe012a20 100644 --- a/packages/backend-app-api/src/services/implementations/permissionsService.ts +++ b/packages/backend-app-api/src/services/implementations/permissionsService.ts @@ -23,6 +23,7 @@ import { } from '@backstage/backend-plugin-api'; import { ServerPermissionClient } from '@backstage/plugin-permission-node'; +/** @public */ export const permissionsFactory = createServiceFactory({ service: permissionsServiceRef, deps: { diff --git a/packages/backend-app-api/src/services/implementations/schedulerService.ts b/packages/backend-app-api/src/services/implementations/schedulerService.ts index 130ccb3f5f..39dbf26ba9 100644 --- a/packages/backend-app-api/src/services/implementations/schedulerService.ts +++ b/packages/backend-app-api/src/services/implementations/schedulerService.ts @@ -21,6 +21,7 @@ import { } from '@backstage/backend-plugin-api'; import { TaskScheduler } from '@backstage/backend-tasks'; +/** @public */ export const schedulerFactory = createServiceFactory({ service: schedulerServiceRef, deps: { diff --git a/packages/backend-app-api/src/services/implementations/tokenManagerService.ts b/packages/backend-app-api/src/services/implementations/tokenManagerService.ts index 2e82fce9d9..7767c17944 100644 --- a/packages/backend-app-api/src/services/implementations/tokenManagerService.ts +++ b/packages/backend-app-api/src/services/implementations/tokenManagerService.ts @@ -23,6 +23,7 @@ import { } from '@backstage/backend-plugin-api'; import { ServerTokenManager } from '@backstage/backend-common'; +/** @public */ export const tokenManagerFactory = createServiceFactory({ service: tokenManagerServiceRef, deps: { diff --git a/packages/backend-app-api/src/services/implementations/urlReaderService.ts b/packages/backend-app-api/src/services/implementations/urlReaderService.ts index 74431dfa0d..df353a52d2 100644 --- a/packages/backend-app-api/src/services/implementations/urlReaderService.ts +++ b/packages/backend-app-api/src/services/implementations/urlReaderService.ts @@ -23,6 +23,7 @@ import { urlReaderServiceRef, } from '@backstage/backend-plugin-api'; +/** @public */ export const urlReaderFactory = createServiceFactory({ service: urlReaderServiceRef, deps: { diff --git a/packages/backend-app-api/src/wiring/BackendInitializer.ts b/packages/backend-app-api/src/wiring/BackendInitializer.ts index ab086f4144..355fa6001d 100644 --- a/packages/backend-app-api/src/wiring/BackendInitializer.ts +++ b/packages/backend-app-api/src/wiring/BackendInitializer.ts @@ -15,19 +15,21 @@ */ import { - BackendRegistrable, + BackendFeature, ExtensionPoint, ServiceRef, } from '@backstage/backend-plugin-api'; -import { BackendRegisterInit, ServiceHolder } from './types'; - -type ServiceOrExtensionPoint = ExtensionPoint | ServiceRef; +import { + BackendRegisterInit, + ServiceHolder, + ServiceOrExtensionPoint, +} from './types'; export class BackendInitializer { #started = false; - #extensions = new Map(); + #features = new Map(); #registerInits = new Array(); - #extensionPoints = new Map(); + #extensionPoints = new Map, unknown>(); #serviceHolder: ServiceHolder; constructor(serviceHolder: ServiceHolder) { @@ -38,42 +40,56 @@ export class BackendInitializer { deps: { [name: string]: ServiceOrExtensionPoint }, pluginId: string, ) { - return Object.fromEntries( - await Promise.all( - Object.entries(deps).map(async ([name, ref]) => [ - name, - this.#extensionPoints.get(ref) || - (await this.#serviceHolder.get(ref as ServiceRef)!( - pluginId, - )), - ]), - ), - ); - } + const result = new Map(); + const missingRefs = new Set(); - add(extension: BackendRegistrable, options?: TOptions) { - if (this.#started) { + for (const [name, ref] of Object.entries(deps)) { + const extensionPoint = this.#extensionPoints.get( + ref as ExtensionPoint, + ); + if (extensionPoint) { + result.set(name, extensionPoint); + } else { + const factory = await this.#serviceHolder.get( + ref as ServiceRef, + ); + if (factory) { + result.set(name, await factory(pluginId)); + } else { + missingRefs.add(ref); + } + } + } + + if (missingRefs.size > 0) { + const missing = Array.from(missingRefs).join(', '); throw new Error( - 'extension can not be added after the backend has started', + `No extension point or service available for the following ref(s): ${missing}`, ); } - this.#extensions.set(extension, options); + + return Object.fromEntries(result); + } + + add(feature: BackendFeature, options?: TOptions) { + if (this.#started) { + throw new Error('feature can not be added after the backend has started'); + } + this.#features.set(feature, options); } async start(): Promise { - console.log(`Starting backend`); if (this.#started) { throw new Error('Backend has already started'); } this.#started = true; - for (const [extension] of this.#extensions) { - const provides = new Set>(); + for (const [feature] of this.#features) { + const provides = new Set>(); let registerInit: BackendRegisterInit | undefined = undefined; - console.log('Registering', extension.id); - extension.register({ + feature.register({ registerExtensionPoint: (extensionPointRef, impl) => { if (registerInit) { throw new Error('registerExtensionPoint called after registerInit'); @@ -89,10 +105,12 @@ export class BackendInitializer { throw new Error('registerInit must only be called once'); } registerInit = { - id: extension.id, + id: feature.id, provides, consumes: new Set(Object.values(registerOptions.deps)), - deps: registerOptions.deps, + deps: registerOptions.deps as { + [name: string]: ServiceOrExtensionPoint; + }, init: registerOptions.init as BackendRegisterInit['init'], }; }, @@ -100,15 +118,13 @@ export class BackendInitializer { if (!registerInit) { throw new Error( - `registerInit was not called by register in ${extension.id}`, + `registerInit was not called by register in ${feature.id}`, ); } this.#registerInits.push(registerInit); } - this.validateSetup(); - const orderedRegisterResults = this.#resolveInitOrder(this.#registerInits); for (const registerInit of orderedRegisterResults) { @@ -117,8 +133,6 @@ export class BackendInitializer { } } - private validateSetup() {} - #resolveInitOrder(registerInits: Array) { let registerInitsToOrder = registerInits.slice(); const orderedRegisterInits = new Array(); @@ -131,18 +145,17 @@ export class BackendInitializer { for (const registerInit of registerInitsToOrder) { const unInitializedDependents = []; - for (const serviceRef of registerInit.provides) { + for (const provided of registerInit.provides) { if ( registerInitsToOrder.some( - init => init !== registerInit && init.consumes.has(serviceRef), + init => init !== registerInit && init.consumes.has(provided), ) ) { - unInitializedDependents.push(serviceRef); + unInitializedDependents.push(provided); } } if (unInitializedDependents.length === 0) { - console.log(`DEBUG: pushed ${registerInit.id} to results`); orderedRegisterInits.push(registerInit); toRemove.add(registerInit); } @@ -150,6 +163,7 @@ export class BackendInitializer { registerInitsToOrder = registerInitsToOrder.filter(r => !toRemove.has(r)); } + return orderedRegisterInits; } } diff --git a/packages/backend-app-api/src/wiring/BackstageBackend.ts b/packages/backend-app-api/src/wiring/BackstageBackend.ts index 104d2b6fc8..1d76161bfe 100644 --- a/packages/backend-app-api/src/wiring/BackstageBackend.ts +++ b/packages/backend-app-api/src/wiring/BackstageBackend.ts @@ -14,10 +14,7 @@ * limitations under the License. */ -import { - AnyServiceFactory, - BackendRegistrable, -} from '@backstage/backend-plugin-api'; +import { ServiceFactory, BackendFeature } from '@backstage/backend-plugin-api'; import { BackendInitializer } from './BackendInitializer'; import { ServiceRegistry } from './ServiceRegistry'; import { Backend } from './types'; @@ -26,13 +23,13 @@ export class BackstageBackend implements Backend { #services: ServiceRegistry; #initializer: BackendInitializer; - constructor(apiFactories: AnyServiceFactory[]) { + constructor(apiFactories: ServiceFactory[]) { this.#services = new ServiceRegistry(apiFactories); this.#initializer = new BackendInitializer(this.#services); } - add(extension: BackendRegistrable): void { - this.#initializer.add(extension); + add(feature: BackendFeature): void { + this.#initializer.add(feature); } async start(): Promise { diff --git a/packages/backend-app-api/src/wiring/ServiceRegistry.test.ts b/packages/backend-app-api/src/wiring/ServiceRegistry.test.ts new file mode 100644 index 0000000000..acdd2a4c41 --- /dev/null +++ b/packages/backend-app-api/src/wiring/ServiceRegistry.test.ts @@ -0,0 +1,173 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createServiceRef, + createServiceFactory, +} from '@backstage/backend-plugin-api'; +import { ServiceRegistry } from './ServiceRegistry'; + +const ref1 = createServiceRef<{ x: number; pluginId: string }>({ + id: '1', +}); +const sf1 = createServiceFactory({ + service: ref1, + deps: {}, + factory: async () => { + return async pluginId => { + return { x: 1, pluginId }; + }; + }, +}); + +const ref2 = createServiceRef<{ x: number; pluginId: string }>({ + id: '2', +}); +const sf2 = createServiceFactory({ + service: ref2, + deps: {}, + factory: async () => { + return async pluginId => { + return { x: 2, pluginId }; + }; + }, +}); +const sf2b = createServiceFactory({ + service: ref2, + deps: {}, + factory: async () => { + return async pluginId => { + return { x: 22, pluginId }; + }; + }, +}); + +const refDefault1 = createServiceRef<{ x: number; pluginId: string }>({ + id: '1', + defaultFactory: async service => + createServiceFactory({ + service, + deps: {}, + factory: async () => async pluginId => ({ x: 10, pluginId }), + }), +}); + +const refDefault2a = createServiceRef<{ x: number; pluginId: string }>({ + id: '2a', + defaultFactory: async service => + createServiceFactory({ + service, + deps: {}, + factory: async () => async pluginId => ({ x: 20, pluginId }), + }), +}); + +const refDefault2b = createServiceRef<{ x: number; pluginId: string }>({ + id: '2b', + defaultFactory: async service => + createServiceFactory({ + service, + deps: {}, + factory: async () => async pluginId => ({ x: 220, pluginId }), + }), +}); + +describe('ServiceRegistry', () => { + it('should return undefined if there is no factory defined', async () => { + const registry = new ServiceRegistry([]); + expect(registry.get(ref1)).toBe(undefined); + }); + + it('should return a factory for a registered ref', async () => { + const registry = new ServiceRegistry([sf1]); + const factory = registry.get(ref1)!; + expect(factory).toEqual(expect.any(Function)); + await expect(factory('catalog')).resolves.toEqual({ + x: 1, + pluginId: 'catalog', + }); + await expect(factory('scaffolder')).resolves.toEqual({ + x: 1, + pluginId: 'scaffolder', + }); + expect(await factory('catalog')).toBe(await factory('catalog')); + }); + + it('should handle multiple factories with different serviceRefs', async () => { + const registry = new ServiceRegistry([sf1, sf2]); + const factory1 = registry.get(ref1)!; + const factory2 = registry.get(ref2)!; + expect(factory1).toEqual(expect.any(Function)); + expect(factory2).toEqual(expect.any(Function)); + await expect(factory1('catalog')).resolves.toEqual({ + x: 1, + pluginId: 'catalog', + }); + await expect(factory2('catalog')).resolves.toEqual({ + x: 2, + pluginId: 'catalog', + }); + expect(await factory1('catalog')).not.toBe(await factory2('catalog')); + }); + + it('should use the last factory for each ref', async () => { + const registry = new ServiceRegistry([sf2, sf2b]); + const factory2 = registry.get(ref2)!; + await expect(factory2('catalog')).resolves.toEqual({ + x: 22, + pluginId: 'catalog', + }); + }); + + it('should return the defaultFactory from the ref if not provided to the registry', async () => { + const registry = new ServiceRegistry([]); + const factory = registry.get(refDefault1)!; + expect(factory).toEqual(expect.any(Function)); + await expect(factory('catalog')).resolves.toEqual({ + x: 10, + pluginId: 'catalog', + }); + }); + + it('should not return the defaultFactory from the ref if provided to the registry', async () => { + const registry = new ServiceRegistry([sf1]); + const factory = registry.get(refDefault1)!; + expect(factory).toEqual(expect.any(Function)); + await expect(factory('catalog')).resolves.toEqual({ + x: 1, + pluginId: 'catalog', + }); + }); + + it('should handle duplicate defaultFactories by duplicating the implementations', async () => { + const registry = new ServiceRegistry([]); + const factoryA = registry.get(refDefault2a)!; + const factoryB = registry.get(refDefault2b)!; + expect(factoryA).toEqual(expect.any(Function)); + expect(factoryB).toEqual(expect.any(Function)); + await expect(factoryA('catalog')).resolves.toEqual({ + x: 20, + pluginId: 'catalog', + }); + await expect(factoryB('catalog')).resolves.toEqual({ + x: 220, + pluginId: 'catalog', + }); + expect(await factoryA('catalog')).toBe(await factoryA('catalog')); + expect(await factoryB('catalog')).toBe(await factoryB('catalog')); + expect(await factoryA('catalog')).not.toBe(await factoryB('catalog')); + }); +}); diff --git a/packages/backend-app-api/src/wiring/ServiceRegistry.ts b/packages/backend-app-api/src/wiring/ServiceRegistry.ts index bdaecf30c6..b471cd67ca 100644 --- a/packages/backend-app-api/src/wiring/ServiceRegistry.ts +++ b/packages/backend-app-api/src/wiring/ServiceRegistry.ts @@ -14,35 +14,47 @@ * limitations under the License. */ import { - AnyServiceFactory, + ServiceFactory, FactoryFunc, ServiceRef, } from '@backstage/backend-plugin-api'; export class ServiceRegistry { - readonly #implementations: Map>; - readonly #factories: Map; + readonly #providedFactories: Map; + readonly #loadedDefaultFactories: Map; + readonly #implementations: Map>; - constructor(factories: AnyServiceFactory[]) { - this.#factories = new Map(factories.map(f => [f.service.id, f])); + constructor(factories: ServiceFactory[]) { + this.#providedFactories = new Map(factories.map(f => [f.service.id, f])); + this.#loadedDefaultFactories = new Map(); this.#implementations = new Map(); } get(ref: ServiceRef): FactoryFunc | undefined { - const factory = this.#factories.get(ref.id); - if (!factory) { + let factory = this.#providedFactories.get(ref.id); + const { defaultFactory } = ref; + if (!factory && !defaultFactory) { return undefined; } return async (pluginId: string): Promise => { - let implementations = this.#implementations.get(ref.id); + if (!factory) { + let loadedFactory = this.#loadedDefaultFactories.get(defaultFactory!); + if (!loadedFactory) { + loadedFactory = (await defaultFactory!(ref)) as ServiceFactory; + this.#loadedDefaultFactories.set(defaultFactory!, loadedFactory); + } + factory = loadedFactory; + } + + let implementations = this.#implementations.get(factory); if (implementations) { if (implementations.has(pluginId)) { return implementations.get(pluginId) as T; } } else { implementations = new Map(); - this.#implementations.set(ref.id, implementations); + this.#implementations.set(factory, implementations); } const factoryDeps = Object.fromEntries( diff --git a/packages/backend-app-api/src/wiring/index.ts b/packages/backend-app-api/src/wiring/index.ts index 1dd91e30e1..2f55076922 100644 --- a/packages/backend-app-api/src/wiring/index.ts +++ b/packages/backend-app-api/src/wiring/index.ts @@ -14,5 +14,9 @@ * limitations under the License. */ -export type { Backend, CreateBackendOptions } from './types'; -export { createBackend } from './types'; +export type { + Backend, + CreateSpecializedBackendOptions, + ServiceOrExtensionPoint, +} from './types'; +export { createSpecializedBackend } from './types'; diff --git a/packages/backend-app-api/src/wiring/types.ts b/packages/backend-app-api/src/wiring/types.ts index 112fe06b05..55009edbdf 100644 --- a/packages/backend-app-api/src/wiring/types.ts +++ b/packages/backend-app-api/src/wiring/types.ts @@ -15,35 +15,35 @@ */ import { - AnyServiceFactory, - BackendRegistrable, + ServiceFactory, + BackendFeature, + ExtensionPoint, FactoryFunc, ServiceRef, } from '@backstage/backend-plugin-api'; -import { defaultServiceFactories } from '../services/implementations'; import { BackstageBackend } from './BackstageBackend'; /** * @public */ export interface Backend { - add(extension: BackendRegistrable): void; + add(feature: BackendFeature): void; start(): Promise; } export interface BackendRegisterInit { id: string; - consumes: Set>; - provides: Set>; - deps: { [name: string]: ServiceRef }; + consumes: Set; + provides: Set; + deps: { [name: string]: ServiceOrExtensionPoint }; init: (deps: { [name: string]: unknown }) => Promise; } /** * @public */ -export interface CreateBackendOptions { - apis: AnyServiceFactory[]; +export interface CreateSpecializedBackendOptions { + services: ServiceFactory[]; } export type ServiceHolder = { @@ -53,10 +53,15 @@ export type ServiceHolder = { /** * @public */ -export function createBackend(options?: CreateBackendOptions): Backend { - // TODO: merge with provided APIs - return new BackstageBackend([ - ...defaultServiceFactories, - ...(options?.apis ?? []), - ]); +export function createSpecializedBackend( + options: CreateSpecializedBackendOptions, +): Backend { + return new BackstageBackend(options.services); } + +/** + * @public + */ +export type ServiceOrExtensionPoint = + | ExtensionPoint + | ServiceRef; diff --git a/packages/backend-common/CHANGELOG.md b/packages/backend-common/CHANGELOG.md index 84370721a8..6068b179e4 100644 --- a/packages/backend-common/CHANGELOG.md +++ b/packages/backend-common/CHANGELOG.md @@ -1,5 +1,105 @@ # @backstage/backend-common +## 0.15.0 + +### Minor Changes + +- 12e9b54f0e: Added back support for when no branch is provided to the `UrlReader` for Bitbucket Server +- 30012e7d8c: - Added `force` and `remoteRef` option to `push` method in `git` actions + - Added `addRemote` and `deleteRemote` methods to `git` actions + +### Patch Changes + +- fc8a5f797b: Improve `scm/git` wrapper around `isomorphic-git` library : + + - Add `checkout` function, + - Add optional `remoteRef` parameter in the `push` function. + +- 5e4dc173f7: Added a second validation to the `dir()` method of ZIP archive responses returned from `readTree()` that ensures that extracted files do not fall outside the target directory. +- 1732a18a7a: Exported `redactLogLine` function to be able to use it in custom loggers and renamed it to `redactWinstonLogLine`. +- 3b7930b3e5: Add support for Bearer Authorization header / token-based auth at Git commands. +- cfa078e255: The `ZipArchiveResponse` now correctly handles corrupt ZIP archives. + + Before this change, certain corrupt ZIP archives either cause the inflater to throw (as expected), or will hang the parser indefinitely. + + By switching out the `zip` parsing library, we now write to a temporary directory, and load from disk which should ensure that the parsing of the `.zip` files are done correctly because `streaming` of `zip` paths is technically impossible without being able to parse the headers at the end of the file. + +- 770d3f92c4: The config prop `ensureExists` now applies to schema creation when `pluginDivisionMode` is set to `schema`. This means schemas will no longer accidentally be automatically created when `ensureExists` is set to `false`. +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/integration@1.3.0 + +## 0.15.0-next.2 + +### Patch Changes + +- 5e4dc173f7: Added a second validation to the `dir()` method of ZIP archive responses returned from `readTree()` that ensures that extracted files do not fall outside the target directory. + +## 0.15.0-next.1 + +### Patch Changes + +- 1732a18a7a: Exported `redactLogLine` function to be able to use it in custom loggers and renamed it to `redactWinstonLogLine`. +- Updated dependencies + - @backstage/integration@1.3.0-next.1 + +## 0.15.0-next.0 + +### Minor Changes + +- 12e9b54f0e: Added back support for when no branch is provided to the `UrlReader` for Bitbucket Server +- 30012e7d8c: - Added `force` and `remoteRef` option to `push` method in `git` actions + - Added `addRemote` and `deleteRemote` methods to `git` actions + +### Patch Changes + +- fc8a5f797b: Improve `scm/git` wrapper around `isomorphic-git` library : + + - Add `checkout` function, + - Add optional `remoteRef` parameter in the `push` function. + +- 3b7930b3e5: Add support for Bearer Authorization header / token-based auth at Git commands. +- cfa078e255: The `ZipArchiveResponse` now correctly handles corrupt ZIP archives. + + Before this change, certain corrupt ZIP archives either cause the inflater to throw (as expected), or will hang the parser indefinitely. + + By switching out the `zip` parsing library, we now write to a temporary directory, and load from disk which should ensure that the parsing of the `.zip` files are done correctly because `streaming` of `zip` paths is technically impossible without being able to parse the headers at the end of the file. + +- 770d3f92c4: The config prop `ensureExists` now applies to schema creation when `pluginDivisionMode` is set to `schema`. This means schemas will no longer accidentally be automatically created when `ensureExists` is set to `false`. +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + +## 0.14.1 + +### Patch Changes + +- b1edb5cfd9: Fix parsing of S3 URLs for the default region. +- c3cfc83af2: Updated JSDoc to be MDX compatible. +- e57180e45e: Added some more information to the error messages for `isomorphic-git` errors +- 1f75dfac29: Fix edge case bug when gitlab relativePath is repeated in the target URL. +- 90c87f28e8: Moving from Bitbucket Server endpoint from https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp222 to https://docs.atlassian.com/bitbucket-server/rest/7.9.0/bitbucket-rest.html#idp224, to have the last commit in function of different branch, and not only the list of default branch +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 +- 0fc57887e8: Improve plural handling in logging output for secrets +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 954a94f52f: Support self-hosted gitlab installations with relative URL. +- Updated dependencies + - @backstage/config-loader@1.1.3 + - @backstage/integration@1.2.2 + - @backstage/errors@1.1.0 + ## 0.14.1-next.3 ### Patch Changes diff --git a/packages/backend-common/api-report.md b/packages/backend-common/api-report.md index 6059e68792..8362c3ab2f 100644 --- a/packages/backend-common/api-report.md +++ b/packages/backend-common/api-report.md @@ -338,7 +338,10 @@ export class Git { dir: string; remote: string; url: string; + force?: boolean; }): Promise; + // (undocumented) + checkout(options: { dir: string; ref: string }): Promise; clone(options: { url: string; dir: string; @@ -363,11 +366,14 @@ export class Git { dir: string; fullName?: boolean; }): Promise; + // (undocumented) + deleteRemote(options: { dir: string; remote: string }): Promise; fetch(options: { dir: string; remote?: string }): Promise; // (undocumented) static fromAuth: (options: { username?: string; password?: string; + token?: string; logger?: Logger; }) => Git; // (undocumented) @@ -387,7 +393,12 @@ export class Git { }; }): Promise; // (undocumented) - push(options: { dir: string; remote: string }): Promise; + push(options: { + dir: string; + remote: string; + remoteRef?: string; + force?: boolean; + }): Promise; readCommit(options: { dir: string; sha: string }): Promise; resolveRef(options: { dir: string; ref: string }): Promise; } @@ -568,6 +579,11 @@ export type ReadUrlResponseFactoryFromStreamOptions = { etag?: string; }; +// @public +export function redactWinstonLogLine( + info: winston.Logform.TransformableInfo, +): winston.Logform.TransformableInfo; + // @public export function requestLoggingHandler(logger?: Logger): RequestHandler; diff --git a/packages/backend-common/package.json b/packages/backend-common/package.json index cb2f653277..7cdedf0c21 100644 --- a/packages/backend-common/package.json +++ b/packages/backend-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-common", "description": "Common functionality library for Backstage backends", - "version": "0.14.1-next.3", + "version": "0.15.0", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -36,17 +36,18 @@ "dependencies": { "@backstage/cli-common": "^0.1.9", "@backstage/config": "^1.0.1", - "@backstage/config-loader": "^1.1.3-next.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", + "@backstage/config-loader": "^1.1.3", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", "@backstage/types": "^1.0.0", "@google-cloud/storage": "^6.0.0", + "@keyv/redis": "^2.2.3", "@manypkg/get-packages": "^1.1.3", "@octokit/rest": "^19.0.3", "@types/cors": "^2.8.6", "@types/dockerode": "^3.3.0", "@types/express": "^4.17.6", - "@types/luxon": "^2.0.4", + "@types/luxon": "^3.0.0", "@types/webpack-env": "^1.15.2", "archiver": "^5.0.2", "aws-sdk": "^2.840.0", @@ -64,7 +65,6 @@ "jose": "^4.6.0", "keyv": "^4.0.3", "keyv-memcache": "^1.2.5", - "@keyv/redis": "^2.2.3", "knex": "^2.0.0", "lodash": "^4.17.21", "logform": "^2.3.2", @@ -78,8 +78,8 @@ "selfsigned": "^2.0.0", "stoppable": "^1.1.0", "tar": "^6.1.2", - "unzipper": "^0.10.11", "winston": "^3.2.1", + "yauzl": "^2.10.0", "yn": "^4.0.0" }, "peerDependencies": { @@ -91,8 +91,8 @@ } }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "@types/archiver": "^5.1.0", "@types/base64-stream": "^1.0.2", "@types/compression": "^1.7.0", @@ -106,13 +106,13 @@ "@types/stoppable": "^1.1.0", "@types/supertest": "^2.0.8", "@types/tar": "^6.1.1", - "@types/unzipper": "^0.10.3", + "@types/yauzl": "^2.10.0", "@types/webpack-env": "^1.15.2", "aws-sdk-mock": "^5.2.1", "better-sqlite3": "^7.5.0", "http-errors": "^2.0.0", "mock-fs": "^5.1.0", - "msw": "^0.44.0", + "msw": "^0.45.0", "mysql2": "^2.2.5", "recursive-readdir": "^2.2.2", "supertest": "^6.1.3" diff --git a/packages/backend-common/src/database/DatabaseManager.test.ts b/packages/backend-common/src/database/DatabaseManager.test.ts index ea8aca38ea..9e8af44fc0 100644 --- a/packages/backend-common/src/database/DatabaseManager.test.ts +++ b/packages/backend-common/src/database/DatabaseManager.test.ts @@ -612,6 +612,31 @@ describe('DatabaseManager', () => { ); }); + it('ensureExists does not create database or schema when false', async () => { + const testManager = DatabaseManager.fromConfig( + new ConfigReader({ + backend: { + database: { + client: 'pg', + pluginDivisionMode: 'schema', + ensureExists: false, + connection: { + host: 'localhost', + user: 'foo', + password: 'bar', + database: 'foodb', + }, + }, + }, + }), + ); + const pluginId = 'testdbname'; + await testManager.forPlugin(pluginId).getClient(); + + expect(mocked(ensureDatabaseExists)).toHaveBeenCalledTimes(0); + expect(mocked(ensureSchemaExists)).toHaveBeenCalledTimes(0); + }); + it('fetches and merges additional knex config', async () => { const testManager = DatabaseManager.fromConfig( new ConfigReader({ diff --git a/packages/backend-common/src/database/DatabaseManager.ts b/packages/backend-common/src/database/DatabaseManager.ts index 004e7d13cd..39ff864f8c 100644 --- a/packages/backend-common/src/database/DatabaseManager.ts +++ b/packages/backend-common/src/database/DatabaseManager.ts @@ -321,13 +321,15 @@ export class DatabaseManager { let schemaOverrides; if (this.getPluginDivisionModeConfig() === 'schema') { - try { - schemaOverrides = this.getSchemaOverrides(pluginId); - await ensureSchemaExists(pluginConfig, pluginId); - } catch (error) { - throw new Error( - `Failed to connect to the database to make sure that schema for plugin '${pluginId}' exists, ${error}`, - ); + schemaOverrides = this.getSchemaOverrides(pluginId); + if (this.getEnsureExistsConfig(pluginId)) { + try { + await ensureSchemaExists(pluginConfig, pluginId); + } catch (error) { + throw new Error( + `Failed to connect to the database to make sure that schema for plugin '${pluginId}' exists, ${error}`, + ); + } } } diff --git a/packages/backend-common/src/logging/index.ts b/packages/backend-common/src/logging/index.ts index f50114a9ae..4657dd4101 100644 --- a/packages/backend-common/src/logging/index.ts +++ b/packages/backend-common/src/logging/index.ts @@ -15,5 +15,10 @@ */ export * from './formats'; -export { createRootLogger, getRootLogger, setRootLogger } from './rootLogger'; +export { + createRootLogger, + getRootLogger, + setRootLogger, + redactWinstonLogLine, +} from './rootLogger'; export * from './voidLogger'; diff --git a/packages/backend-common/src/logging/rootLogger.ts b/packages/backend-common/src/logging/rootLogger.ts index 87180bde8f..6077662dcf 100644 --- a/packages/backend-common/src/logging/rootLogger.ts +++ b/packages/backend-common/src/logging/rootLogger.ts @@ -69,8 +69,10 @@ export function setRootLoggerRedactionList(redactionList: string[]) { /** * A winston formatting function that finds occurrences of filteredKeys * and replaces them with the corresponding identifier. + * + * @public */ -function redactLogLine(info: winston.Logform.TransformableInfo) { +export function redactWinstonLogLine(info: winston.Logform.TransformableInfo) { // TODO(hhogg): The logger is created before the config is loaded, because the // logger is needed in the config loader. There is a risk of a secret being // logged out during the config loading stage. @@ -104,7 +106,7 @@ export function createRootLogger( { level: env.LOG_LEVEL || 'info', format: winston.format.combine( - winston.format(redactLogLine)(), + winston.format(redactWinstonLogLine)(), env.NODE_ENV === 'production' ? winston.format.json() : coloredFormat, ), defaultMeta: { diff --git a/packages/backend-common/src/reading/BitbucketServerUrlReader.test.ts b/packages/backend-common/src/reading/BitbucketServerUrlReader.test.ts index 4584ba75f8..f308b4d33d 100644 --- a/packages/backend-common/src/reading/BitbucketServerUrlReader.test.ts +++ b/packages/backend-common/src/reading/BitbucketServerUrlReader.test.ts @@ -109,6 +109,55 @@ describe('BitbucketServerUrlReader', () => { }); }); + describe('readTree without branch', () => { + const repoBuffer = fs.readFileSync( + path.resolve(__dirname, '__fixtures__/bitbucket-server-repo.tar.gz'), + ); + + beforeEach(() => { + worker.use( + rest.get( + 'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/archive', + (_, res, ctx) => + res( + ctx.status(200), + ctx.set('Content-Type', 'application/zip'), + ctx.set( + 'content-disposition', + 'attachment; filename=backstage-mock.tgz', + ), + ctx.body(repoBuffer), + ), + ), + rest.get( + 'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/commits/*', + (_, res, ctx) => + res( + ctx.status(200), + ctx.json({ + values: [{ id: '12ab34cd56ef78gh90ij12kl34mn56op78qr90st' }], + }), + ), + ), + ); + }); + + it('uses private bitbucket host', async () => { + const response = await reader.readTree( + 'https://bitbucket.mycompany.net/projects/backstage/repos/mock/browse/docs?at=some-branch', + ); + + expect(response.etag).toBe('12ab34cd56ef'); + + const files = await response.files(); + + expect(files.length).toBe(1); + const indexMarkdownFile = await files[0].content(); + + expect(indexMarkdownFile.toString()).toBe('# Test\n'); + }); + }); + describe('search private', () => { const repoBuffer = fs.readFileSync( path.resolve(__dirname, '__fixtures__/bitbucket-server-repo.tar.gz'), diff --git a/packages/backend-common/src/reading/BitbucketServerUrlReader.ts b/packages/backend-common/src/reading/BitbucketServerUrlReader.ts index 31894cf823..e9a229a1ff 100644 --- a/packages/backend-common/src/reading/BitbucketServerUrlReader.ts +++ b/packages/backend-common/src/reading/BitbucketServerUrlReader.ts @@ -205,10 +205,21 @@ export class BitbucketServerUrlReader implements UrlReader { const commits = await commitResponse.json(); + // Handles case when a branch is provided in the URL if (commits && commits.id) { return commits.id.substring(0, 12); } + // Handles case when no branch is provided in the URL + if ( + commits && + commits.values && + commits.values.length > 0 && + commits.values[0].id + ) { + return commits.values[0].id.substring(0, 12); + } + throw new Error(`Failed to read response from ${commitApiUrl}`); } } diff --git a/packages/backend-common/src/reading/GitlabUrlReader.test.ts b/packages/backend-common/src/reading/GitlabUrlReader.test.ts index f422820a29..29ef3f4ce8 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.test.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.test.ts @@ -106,7 +106,7 @@ describe('GitlabUrlReader', () => { ); it.each([ - // Project URLs + // Scoped routes { url: 'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml', config: createConfig(), @@ -135,12 +135,12 @@ describe('GitlabUrlReader', () => { }), }, - // Raw URLs + // Unscoped route { url: 'https://gitlab.example.com/a/b/blob/master/c.yaml', config: createConfig(), response: expect.objectContaining({ - url: 'https://gitlab.example.com/a/b/raw/master/c.yaml', + url: 'https://gitlab.example.com/api/v4/projects/12345/repository/files/c.yaml/raw?ref=master', }), }, ])('should handle happy path %#', async ({ url, config, response }) => { diff --git a/packages/backend-common/src/reading/GitlabUrlReader.ts b/packages/backend-common/src/reading/GitlabUrlReader.ts index 5bc234daef..eaa15a7208 100644 --- a/packages/backend-common/src/reading/GitlabUrlReader.ts +++ b/packages/backend-common/src/reading/GitlabUrlReader.ts @@ -125,8 +125,12 @@ export class GitlabUrlReader implements UrlReader { ); // Considering self hosted gitlab with relative + // assuming '/gitlab' is the relative path + // from: /gitlab/repo/project + // to: repo/project if (relativePath) { - repoFullName = trimStart(full_name, relativePath); + const rectifiedRelativePath = `${trimStart(relativePath, '/')}/`; + repoFullName = full_name.replace(rectifiedRelativePath, ''); } // Use GitLab API to get the default branch diff --git a/packages/backend-common/src/reading/__fixtures__/mallory.zip b/packages/backend-common/src/reading/__fixtures__/mallory.zip new file mode 100644 index 0000000000..e45bd798b3 Binary files /dev/null and b/packages/backend-common/src/reading/__fixtures__/mallory.zip differ diff --git a/packages/backend-common/src/reading/__fixtures__/mock-corrupted.zip b/packages/backend-common/src/reading/__fixtures__/mock-corrupted.zip new file mode 100644 index 0000000000..5130a72f6f Binary files /dev/null and b/packages/backend-common/src/reading/__fixtures__/mock-corrupted.zip differ diff --git a/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts b/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts index a54bac0c4a..427c237802 100644 --- a/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts +++ b/packages/backend-common/src/reading/tree/ZipArchiveResponse.test.ts @@ -22,15 +22,23 @@ import { ZipArchiveResponse } from './ZipArchiveResponse'; const archiveData = fs.readFileSync( resolvePath(__filename, '../../__fixtures__/mock-main.zip'), ); +const archiveDataCorrupted = fs.readFileSync( + resolvePath(__filename, '../../__fixtures__/mock-corrupted.zip'), +); const archiveDataWithExtraDir = fs.readFileSync( resolvePath(__filename, '../../__fixtures__/mock-with-extra-root-dir.zip'), ); +const archiveWithMaliciousEntry = fs.readFileSync( + resolvePath(__filename, '../../__fixtures__/mallory.zip'), +); describe('ZipArchiveResponse', () => { beforeEach(() => { mockFs({ '/test-archive.zip': archiveData, '/test-archive-with-extra-root-dir.zip': archiveDataWithExtraDir, + '/test-archive-corrupted.zip': archiveDataCorrupted, + '/test-archive-malicious.zip': archiveWithMaliciousEntry, '/tmp': mockFs.directory(), }); }); @@ -55,6 +63,7 @@ describe('ZipArchiveResponse', () => { content: expect.any(Function), }, ]); + const contents = await Promise.all(files.map(f => f.content())); expect(contents.map(c => c.toString('utf8').trim())).toEqual([ 'site_name: Test', @@ -129,7 +138,6 @@ describe('ZipArchiveResponse', () => { const res = new ZipArchiveResponse(stream, 'docs/', '/tmp', 'etag'); const dir = await res.dir(); - expect(dir).toMatch(/^[\/\\]tmp[\/\\].*$/); await expect( fs.readFile(resolvePath(dir, 'index.md'), 'utf8'), @@ -152,4 +160,33 @@ describe('ZipArchiveResponse', () => { fs.pathExists(resolvePath(dir, 'docs/index.md')), ).resolves.toBe(false); }); + + it('should throw on invalid archive', async () => { + const stream = fs.createReadStream('/test-archive-corrupted.zip'); + + const res = new ZipArchiveResponse(stream, '', '/tmp', 'etag'); + const filesPromise = res.files(); + + await expect(filesPromise).rejects.toThrow( + 'invalid comment length. expected: 55. found: 0', + ); + }); + + it('should throw on entries with a path outside the destination dir', async () => { + const stream = fs.createReadStream('/test-archive-malicious.zip'); + + const res = new ZipArchiveResponse(stream, '', '/tmp', 'etag'); + await expect(res.files()).rejects.toThrow( + 'invalid relative path: ../side.txt', + ); + }); + + it('should throw on entries that attempt to write outside destination dir', async () => { + const stream = fs.createReadStream('/test-archive-malicious.zip'); + + const res = new ZipArchiveResponse(stream, '', '/tmp', 'etag'); + await expect(res.dir()).rejects.toThrow( + 'invalid relative path: ../side.txt', + ); + }); }); diff --git a/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts b/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts index e07cedde87..4100af3d57 100644 --- a/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts +++ b/packages/backend-common/src/reading/tree/ZipArchiveResponse.ts @@ -15,15 +15,17 @@ */ import archiver from 'archiver'; +import yauzl, { Entry } from 'yauzl'; import fs from 'fs-extra'; import platformPath from 'path'; import { Readable } from 'stream'; -import unzipper, { Entry } from 'unzipper'; import { ReadTreeResponse, ReadTreeResponseDirOptions, ReadTreeResponseFile, } from '../types'; +import { streamToBuffer } from './util'; +import { resolveSafeChildPath } from '../../paths'; /** * Wraps a zip archive stream into a tree response reader. @@ -67,43 +69,85 @@ export class ZipArchiveResponse implements ReadTreeResponse { private shouldBeIncluded(entry: Entry): boolean { if (this.subPath) { - if (!entry.path.startsWith(this.subPath)) { + if (!entry.fileName.startsWith(this.subPath)) { return false; } } if (this.filter) { - return this.filter(this.getInnerPath(entry.path), { - size: - (entry.vars as { uncompressedSize?: number }).uncompressedSize ?? - entry.vars.compressedSize, + return this.filter(this.getInnerPath(entry.fileName), { + size: entry.uncompressedSize, }); } return true; } - async files(): Promise { - this.onlyOnce(); + private async streamToTemporaryFile( + stream: Readable, + ): Promise<{ fileName: string; cleanup: () => Promise }> { + const tmpDir = await fs.mkdtemp( + platformPath.join(this.workDir, 'backstage-tmp'), + ); + const tmpFile = platformPath.join(tmpDir, 'tmp.zip'); - const files = Array(); + const writeStream = fs.createWriteStream(tmpFile); - await this.stream - .pipe(unzipper.Parse()) - .on('entry', (entry: Entry) => { - if (entry.type === 'Directory') { - entry.resume(); + return new Promise((resolve, reject) => { + writeStream.on('error', reject); + writeStream.on('finish', () => + resolve({ fileName: tmpFile, cleanup: () => fs.remove(tmpFile) }), + ); + stream.pipe(writeStream); + }); + } + + private forEveryZipEntry( + zip: string, + callback: (entry: Entry, content: Readable) => Promise, + ): Promise { + return new Promise((resolve, reject) => { + yauzl.open(zip, { lazyEntries: true }, (err, zipfile) => { + if (err || !zipfile) { + reject(err || new Error(`Failed to open zip file ${zip}`)); return; } - if (this.shouldBeIncluded(entry)) { - files.push({ - path: this.getInnerPath(entry.path), - content: () => entry.buffer(), - }); - } else { - entry.autodrain(); - } - }) - .promise(); + zipfile.on('entry', async (entry: Entry) => { + // Check that the file is not a directory, and that is matches the filter. + if (!entry.fileName.endsWith('/') && this.shouldBeIncluded(entry)) { + zipfile.openReadStream(entry, async (openErr, readStream) => { + if (openErr || !readStream) { + reject( + openErr || + new Error(`Failed to open zip entry ${entry.fileName}`), + ); + return; + } + + await callback(entry, readStream); + }); + } + zipfile.readEntry(); + }); + zipfile.once('end', () => resolve()); + zipfile.on('error', e => reject(e)); + zipfile.readEntry(); + }); + }); + } + + async files(): Promise { + this.onlyOnce(); + const files = Array(); + const temporary = await this.streamToTemporaryFile(this.stream); + + await this.forEveryZipEntry(temporary.fileName, async (entry, content) => { + files.push({ + path: this.getInnerPath(entry.fileName), + content: async () => await streamToBuffer(content), + }); + }); + + temporary.cleanup(); return files; } @@ -116,45 +160,46 @@ export class ZipArchiveResponse implements ReadTreeResponse { } const archive = archiver('zip'); - await this.stream - .pipe(unzipper.Parse()) - .on('entry', (entry: Entry) => { - if (entry.type === 'File' && this.shouldBeIncluded(entry)) { - archive.append(entry, { name: this.getInnerPath(entry.path) }); - } else { - entry.autodrain(); - } - }) - .promise(); + const temporary = await this.streamToTemporaryFile(this.stream); + + await this.forEveryZipEntry(temporary.fileName, async (entry, content) => { + archive.append(await streamToBuffer(content), { + name: this.getInnerPath(entry.fileName), + }); + }); + archive.finalize(); + temporary.cleanup(); + return archive; } async dir(options?: ReadTreeResponseDirOptions): Promise { this.onlyOnce(); - const dir = options?.targetDir ?? (await fs.mkdtemp(platformPath.join(this.workDir, 'backstage-'))); - await this.stream - .pipe(unzipper.Parse()) - .on('entry', async (entry: Entry) => { - // Ignore directory entries since we handle that with the file entries - // as a zip can have files with directories without directory entries - if (entry.type === 'File' && this.shouldBeIncluded(entry)) { - const entryPath = this.getInnerPath(entry.path); - const dirname = platformPath.dirname(entryPath); - if (dirname) { - await fs.mkdirp(platformPath.join(dir, dirname)); - } - entry.pipe(fs.createWriteStream(platformPath.join(dir, entryPath))); - } else { - entry.autodrain(); - } - }) - .promise(); + const temporary = await this.streamToTemporaryFile(this.stream); + + await this.forEveryZipEntry(temporary.fileName, async (entry, content) => { + const entryPath = this.getInnerPath(entry.fileName); + const dirname = platformPath.dirname(entryPath); + + if (dirname) { + await fs.mkdirp(resolveSafeChildPath(dir, dirname)); + } + return new Promise(async (resolve, reject) => { + const file = fs.createWriteStream(resolveSafeChildPath(dir, entryPath)); + file.on('finish', resolve); + + content.on('error', reject); + content.pipe(file); + }); + }); + + temporary.cleanup(); return dir; } diff --git a/packages/backend-common/src/reading/tree/util.ts b/packages/backend-common/src/reading/tree/util.ts index cfb986a0b0..63192102f4 100644 --- a/packages/backend-common/src/reading/tree/util.ts +++ b/packages/backend-common/src/reading/tree/util.ts @@ -14,12 +14,28 @@ * limitations under the License. */ +import { Readable, pipeline as pipelineCb } from 'stream'; +import { promisify } from 'util'; +import concatStream from 'concat-stream'; + +const pipeline = promisify(pipelineCb); + // Matches a directory name + one `/` at the start of any string, // containing any character except `/` one or more times, and ending with a `/` // e.g. Will match `dirA/` in `dirA/dirB/file.ext` const directoryNameRegex = /^[^\/]+\//; - // Removes the first segment of a forward-slash-separated path export function stripFirstDirectoryFromPath(path: string): string { return path.replace(directoryNameRegex, ''); } + +// Collect the stream into a buffer and return +export const streamToBuffer = (stream: Readable): Promise => { + return new Promise(async (resolve, reject) => { + try { + await pipeline(stream, concatStream(resolve)); + } catch (ex) { + reject(ex); + } + }); +}; diff --git a/packages/backend-common/src/scm/git.test.ts b/packages/backend-common/src/scm/git.test.ts index 46aa0804b6..e9c66a896e 100644 --- a/packages/backend-common/src/scm/git.test.ts +++ b/packages/backend-common/src/scm/git.test.ts @@ -26,6 +26,7 @@ describe('Git', () => { beforeEach(() => { jest.resetAllMocks(); }); + describe('add', () => { it('should call isomorphic-git add with the correct arguments', async () => { const git = Git.fromAuth({}); @@ -48,14 +49,48 @@ describe('Git', () => { const dir = 'mockdirectory'; const remote = 'origin'; const url = 'git@github.com/something/sads'; + const force = true; - await git.addRemote({ dir, remote, url }); + await git.addRemote({ dir, remote, url, force }); expect(isomorphic.addRemote).toHaveBeenCalledWith({ fs, dir, remote, url, + force, + }); + }); + }); + + describe('deleteRemote', () => { + it('should call isomorphic-git with the correct arguments', async () => { + const git = Git.fromAuth({}); + const dir = 'mockdirectory'; + const remote = 'origin'; + + await git.deleteRemote({ dir, remote }); + + expect(isomorphic.deleteRemote).toHaveBeenCalledWith({ + fs, + dir, + remote, + }); + }); + }); + + describe('checkout', () => { + it('should call isomorphic-git with the correct arguments', async () => { + const git = Git.fromAuth({}); + const dir = 'mockdirectory'; + const ref = 'master'; + + await git.checkout({ dir, ref }); + + expect(isomorphic.checkout).toHaveBeenCalledWith({ + fs, + dir, + ref, }); }); }); @@ -112,6 +147,33 @@ describe('Git', () => { onAuth: expect.any(Function), }); }); + + it('should call isomorphic-git with the correct arguments (Bearer)', async () => { + const url = 'http://github.com/some/repo'; + const dir = '/some/mock/dir'; + const auth = { + token: 'test', + }; + const git = Git.fromAuth(auth); + + await git.clone({ url, dir }); + + expect(isomorphic.clone).toHaveBeenCalledWith({ + fs, + http, + url, + dir, + singleBranch: true, + depth: 1, + onProgress: expect.any(Function), + headers: { + Authorization: 'Bearer test', + 'user-agent': 'git/@isomorphic-git', + }, + onAuth: expect.any(Function), + }); + }); + it('should pass a function that returns the authorization as the onAuth handler', async () => { const url = 'http://github.com/some/repo'; const dir = '/some/mock/dir'; @@ -129,6 +191,27 @@ describe('Git', () => { expect(onAuth()).toEqual(auth); }); + + it('should propagate the data from the error handler', async () => { + const url = 'http://github.com/some/repo'; + const dir = '/some/mock/dir'; + const auth = { + username: 'blob', + password: 'hunter2', + }; + const git = Git.fromAuth(auth); + + (isomorphic.clone as jest.Mock).mockImplementation(() => { + const error: Error & { data?: unknown } = new Error('mock error'); + error.data = { some: 'more information here' }; + + throw error; + }); + + await expect(git.clone({ url, dir })).rejects.toThrow( + 'more information here', + ); + }); }); describe('currentBranch', () => { @@ -179,6 +262,31 @@ describe('Git', () => { onAuth: expect.any(Function), }); }); + + it('should call isomorphic-git with the correct arguments (Bearer)', async () => { + const remote = 'http://github.com/some/repo'; + const dir = '/some/mock/dir'; + const auth = { + token: 'test', + }; + const git = Git.fromAuth(auth); + + await git.fetch({ remote, dir }); + + expect(isomorphic.fetch).toHaveBeenCalledWith({ + fs, + http, + remote, + dir, + onProgress: expect.any(Function), + headers: { + Authorization: 'Bearer test', + 'user-agent': 'git/@isomorphic-git', + }, + onAuth: expect.any(Function), + }); + }); + it('should pass a function that returns the authorization as the onAuth handler', async () => { const remote = 'http://github.com/some/repo'; const dir = '/some/mock/dir'; @@ -196,6 +304,27 @@ describe('Git', () => { expect(onAuth()).toEqual(auth); }); + + it('should propagate the data from the error handler', async () => { + const remote = 'http://github.com/some/repo'; + const dir = '/some/mock/dir'; + const auth = { + username: 'blob', + password: 'hunter2', + }; + const git = Git.fromAuth(auth); + + (isomorphic.fetch as jest.Mock).mockImplementation(() => { + const error: Error & { data?: unknown } = new Error('mock error'); + error.data = { some: 'more information here' }; + + throw error; + }); + + await expect(git.fetch({ remote, dir })).rejects.toThrow( + 'more information here', + ); + }); }); describe('init', () => { @@ -253,14 +382,72 @@ describe('Git', () => { password: 'hunter2', }; const git = Git.fromAuth(auth); + const remoteRef = 'master'; + const force = true; - await git.push({ dir, remote }); + await git.push({ dir, remote, remoteRef, force }); expect(isomorphic.push).toHaveBeenCalledWith({ fs, http, remote, dir, + remoteRef, + force, + onProgress: expect.any(Function), + headers: { + 'user-agent': 'git/@isomorphic-git', + }, + onAuth: expect.any(Function), + }); + }); + + it('should call isomorphic-git with the correct arguments (Bearer)', async () => { + const remote = 'origin'; + const dir = '/some/mock/dir'; + const auth = { + token: 'test', + }; + const git = Git.fromAuth(auth); + const remoteRef = 'master'; + const force = true; + + await git.push({ dir, remote, remoteRef, force }); + + expect(isomorphic.push).toHaveBeenCalledWith({ + fs, + http, + remote, + dir, + remoteRef, + force, + onProgress: expect.any(Function), + headers: { + Authorization: 'Bearer test', + 'user-agent': 'git/@isomorphic-git', + }, + onAuth: expect.any(Function), + }); + }); + + it('should call isomorphic-git with remoteRef parameter', async () => { + const remote = 'origin'; + const remoteRef = 'refs/for/master'; + const dir = '/some/mock/dir'; + const auth = { + username: 'blob', + password: 'hunter2', + }; + const git = Git.fromAuth(auth); + + await git.push({ dir, remote, remoteRef }); + + expect(isomorphic.push).toHaveBeenCalledWith({ + fs, + http, + remote, + remoteRef, + dir, onProgress: expect.any(Function), headers: { 'user-agent': 'git/@isomorphic-git', @@ -268,6 +455,7 @@ describe('Git', () => { onAuth: expect.any(Function), }); }); + it('should pass a function that returns the authorization as the onAuth handler', async () => { const remote = 'origin'; const dir = '/some/mock/dir'; @@ -276,8 +464,10 @@ describe('Git', () => { password: 'hunter2', }; const git = Git.fromAuth(auth); + const remoteRef = 'master'; + const force = true; - await git.push({ remote, dir }); + await git.push({ remote, dir, remoteRef, force }); const { onAuth } = ( isomorphic.push as unknown as jest.Mock @@ -285,6 +475,29 @@ describe('Git', () => { expect(onAuth()).toEqual(auth); }); + + it('should propagate the data from the error handler', async () => { + const remote = 'origin'; + const dir = '/some/mock/dir'; + const auth = { + username: 'blob', + password: 'hunter2', + }; + const git = Git.fromAuth(auth); + const remoteRef = 'master'; + const force = true; + + (isomorphic.push as jest.Mock).mockImplementation(() => { + const error: Error & { data?: unknown } = new Error('mock error'); + error.data = { some: 'more information here' }; + + throw error; + }); + + await expect(git.push({ remote, dir, remoteRef, force })).rejects.toThrow( + 'more information here', + ); + }); }); describe('readCommit', () => { diff --git a/packages/backend-common/src/scm/git.ts b/packages/backend-common/src/scm/git.ts index 9cf84e9872..8a72c7af89 100644 --- a/packages/backend-common/src/scm/git.ts +++ b/packages/backend-common/src/scm/git.ts @@ -24,13 +24,17 @@ import fs from 'fs-extra'; import { Logger } from 'winston'; /* -provider username password -GitHub 'x-access-token' token -BitBucket 'x-token-auth' token -GitLab 'oauth2' token +provider username password +Azure 'notempty' token +Bitbucket Cloud 'x-token-auth' token +Bitbucket Server username password or token +GitHub 'x-access-token' token +GitLab 'oauth2' token + From : https://isomorphic-git.org/docs/en/onAuth with fix for GitHub -Azure 'notempty' token +Or token provided as `token` for Bearer auth header +instead of Basic Auth (e.g., Bitbucket Server). */ /** @@ -39,13 +43,23 @@ Azure 'notempty' token * @public */ export class Git { + private readonly headers: { + [x: string]: string; + }; + private constructor( private readonly config: { username?: string; password?: string; + token?: string; logger?: Logger; }, - ) {} + ) { + this.headers = { + 'user-agent': 'git/@isomorphic-git', + ...(config.token ? { Authorization: `Bearer ${config.token}` } : {}), + }; + } async add(options: { dir: string; filepath: string }): Promise { const { dir, filepath } = options; @@ -58,12 +72,26 @@ export class Git { dir: string; remote: string; url: string; + force?: boolean; }): Promise { - const { dir, url, remote } = options; + const { dir, url, remote, force } = options; this.config.logger?.info( `Creating new remote {dir=${dir},remote=${remote},url=${url}}`, ); - return git.addRemote({ fs, dir, remote, url }); + return git.addRemote({ fs, dir, remote, url, force }); + } + + async deleteRemote(options: { dir: string; remote: string }): Promise { + const { dir, remote } = options; + this.config.logger?.info(`Deleting remote {dir=${dir},remote=${remote}}`); + return git.deleteRemote({ fs, dir, remote }); + } + + async checkout(options: { dir: string; ref: string }): Promise { + const { dir, ref } = options; + this.config.logger?.info(`Checking out branch {dir=${dir},ref=${ref}}`); + + return git.checkout({ fs, dir, ref }); } async commit(options: { @@ -90,21 +118,28 @@ export class Git { }): Promise { const { url, dir, ref, depth, noCheckout } = options; this.config.logger?.info(`Cloning repo {dir=${dir},url=${url}}`); - return git.clone({ - fs, - http, - url, - dir, - ref, - singleBranch: true, - depth: depth ?? 1, - noCheckout, - onProgress: this.onProgressHandler(), - headers: { - 'user-agent': 'git/@isomorphic-git', - }, - onAuth: this.onAuth, - }); + + try { + return await git.clone({ + fs, + http, + url, + dir, + ref, + singleBranch: true, + depth: depth ?? 1, + noCheckout, + onProgress: this.onProgressHandler(), + headers: this.headers, + onAuth: this.onAuth, + }); + } catch (ex) { + this.config.logger?.error(`Failed to clone repo {dir=${dir},url=${url}}`); + if (ex.data) { + throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`); + } + throw ex; + } } /** https://isomorphic-git.org/docs/en/currentBranch */ @@ -124,15 +159,26 @@ export class Git { this.config.logger?.info( `Fetching remote=${remote} for repository {dir=${dir}}`, ); - await git.fetch({ - fs, - http, - dir, - remote, - onProgress: this.onProgressHandler(), - headers: { 'user-agent': 'git/@isomorphic-git' }, - onAuth: this.onAuth, - }); + + try { + await git.fetch({ + fs, + http, + dir, + remote, + onProgress: this.onProgressHandler(), + headers: this.headers, + onAuth: this.onAuth, + }); + } catch (ex) { + this.config.logger?.error( + `Failed to fetch repo {dir=${dir},origin=${origin}}`, + ); + if (ex.data) { + throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`); + } + throw ex; + } } async init(options: { dir: string; defaultBranch?: string }): Promise { @@ -170,22 +216,37 @@ export class Git { }); } - async push(options: { dir: string; remote: string }) { - const { dir, remote } = options; + async push(options: { + dir: string; + remote: string; + remoteRef?: string; + force?: boolean; + }) { + const { dir, remote, remoteRef, force } = options; this.config.logger?.info( `Pushing directory to remote {dir=${dir},remote=${remote}}`, ); - return git.push({ - fs, - dir, - http, - onProgress: this.onProgressHandler(), - headers: { - 'user-agent': 'git/@isomorphic-git', - }, - remote: remote, - onAuth: this.onAuth, - }); + try { + return await git.push({ + fs, + dir, + http, + onProgress: this.onProgressHandler(), + remoteRef, + force, + headers: this.headers, + remote, + onAuth: this.onAuth, + }); + } catch (ex) { + this.config.logger?.error( + `Failed to push to repo {dir=${dir}, remote=${remote}}`, + ); + if (ex.data) { + throw new Error(`${ex.message} {data=${JSON.stringify(ex.data)}}`); + } + throw ex; + } } /** https://isomorphic-git.org/docs/en/readCommit */ @@ -239,9 +300,10 @@ export class Git { static fromAuth = (options: { username?: string; password?: string; + token?: string; logger?: Logger; }) => { - const { username, password, logger } = options; - return new Git({ username, password, logger }); + const { username, password, token, logger } = options; + return new Git({ username, password, token, logger }); }; } diff --git a/packages/backend-defaults/.eslintrc.js b/packages/backend-defaults/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/packages/backend-defaults/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/packages/backend-defaults/CHANGELOG.md b/packages/backend-defaults/CHANGELOG.md new file mode 100644 index 0000000000..2d80e84fc2 --- /dev/null +++ b/packages/backend-defaults/CHANGELOG.md @@ -0,0 +1,14 @@ +# @backstage/backend-defaults + +## 0.1.0 + +### Minor Changes + +- 5df230d48c: Introduced a new `backend-defaults` package carrying `createBackend` which was previously exported from `backend-app-api`. + The `backend-app-api` package now exports the `createSpecializedBacked` that does not add any service factories by default. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-app-api@0.2.0 + - @backstage/backend-plugin-api@0.1.1 diff --git a/packages/backend-defaults/README.md b/packages/backend-defaults/README.md new file mode 100644 index 0000000000..3128159f7c --- /dev/null +++ b/packages/backend-defaults/README.md @@ -0,0 +1,19 @@ +# @backstage/backend-defaults + +**This package is HIGHLY EXPERIMENTAL, do not use this for production** + +This package provides the core API used by Backstage backend apps. + +## Installation + +Add the library to your backend app package: + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/backend-defaults +``` + +## Documentation + +- [Backstage Readme](https://github.com/backstage/backstage/blob/master/README.md) +- [Backstage Documentation](https://github.com/backstage/backstage/blob/master/docs/README.md) diff --git a/packages/backend-defaults/api-report.md b/packages/backend-defaults/api-report.md new file mode 100644 index 0000000000..b5f1e154bb --- /dev/null +++ b/packages/backend-defaults/api-report.md @@ -0,0 +1,17 @@ +## API Report File for "@backstage/backend-defaults" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Backend } from '@backstage/backend-app-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +// @public (undocumented) +export function createBackend(options?: CreateBackendOptions): Backend; + +// @public (undocumented) +export interface CreateBackendOptions { + // (undocumented) + services?: ServiceFactory[]; +} +``` diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json new file mode 100644 index 0000000000..1270029909 --- /dev/null +++ b/packages/backend-defaults/package.json @@ -0,0 +1,45 @@ +{ + "name": "@backstage/backend-defaults", + "description": "Backend defaults used by Backstage backend apps", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "private": false, + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "node-library" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "packages/backend-defaults" + }, + "keywords": [ + "backstage" + ], + "license": "Apache-2.0", + "scripts": { + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "clean": "backstage-cli package clean", + "start": "backstage-cli package start" + }, + "dependencies": { + "@backstage/backend-app-api": "^0.2.0", + "@backstage/backend-plugin-api": "^0.1.1" + }, + "devDependencies": { + "@backstage/cli": "^0.18.1" + }, + "files": [ + "dist" + ] +} diff --git a/packages/backend-defaults/src/CreateBackend.ts b/packages/backend-defaults/src/CreateBackend.ts new file mode 100644 index 0000000000..819a77ea11 --- /dev/null +++ b/packages/backend-defaults/src/CreateBackend.ts @@ -0,0 +1,70 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + Backend, + cacheFactory, + configFactory, + createSpecializedBackend, + databaseFactory, + discoveryFactory, + httpRouterFactory, + loggerFactory, + permissionsFactory, + schedulerFactory, + tokenManagerFactory, + urlReaderFactory, +} from '@backstage/backend-app-api'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; + +export const defaultServiceFactories = [ + cacheFactory, + configFactory, + databaseFactory, + discoveryFactory, + loggerFactory, + permissionsFactory, + schedulerFactory, + tokenManagerFactory, + urlReaderFactory, + httpRouterFactory, +]; + +/** + * @public + */ +export interface CreateBackendOptions { + services?: ServiceFactory[]; +} + +/** + * @public + */ +export function createBackend(options?: CreateBackendOptions): Backend { + const services = new Map( + defaultServiceFactories.map(sf => [sf.service.id, sf as ServiceFactory]), + ); + + if (options?.services) { + for (const sf of options.services) { + services.set(sf.service.id, sf); + } + } + + return createSpecializedBackend({ + services: Array.from(services.values()), + }); +} diff --git a/packages/backend-defaults/src/index.ts b/packages/backend-defaults/src/index.ts new file mode 100644 index 0000000000..b6ae2f1333 --- /dev/null +++ b/packages/backend-defaults/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Backend defaults used by Backstage backend apps + * + * @packageDocumentation + */ + +export type { CreateBackendOptions } from './CreateBackend'; +export { createBackend } from './CreateBackend'; diff --git a/packages/backend-next/CHANGELOG.md b/packages/backend-next/CHANGELOG.md index 42d40130c9..b8706c0e51 100644 --- a/packages/backend-next/CHANGELOG.md +++ b/packages/backend-next/CHANGELOG.md @@ -1,5 +1,32 @@ # example-backend-next +## 0.0.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.5.0 + - @backstage/backend-defaults@0.1.0 + - @backstage/plugin-catalog-backend@1.3.1 + +## 0.0.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-scaffolder-backend@1.5.0-next.0 + - @backstage/backend-app-api@0.1.1-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## 0.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/plugin-scaffolder-backend@1.4.0 + - @backstage/backend-app-api@0.1.0 + ## 0.0.1-next.0 ### Patch Changes diff --git a/packages/backend-next/package.json b/packages/backend-next/package.json index eba7aec08e..056b6c5722 100644 --- a/packages/backend-next/package.json +++ b/packages/backend-next/package.json @@ -1,6 +1,6 @@ { "name": "example-backend-next", - "version": "0.0.1-next.0", + "version": "0.0.2", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -25,12 +25,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-app-api": "^0.1.0-next.0", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", - "@backstage/plugin-scaffolder-backend": "^1.4.0-next.3" + "@backstage/backend-defaults": "^0.1.0", + "@backstage/plugin-catalog-backend": "^1.3.1", + "@backstage/plugin-scaffolder-backend": "^1.5.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3" + "@backstage/cli": "^0.18.1" }, "files": [ "dist" diff --git a/packages/backend-next/src/index.ts b/packages/backend-next/src/index.ts index 6463dc7ed5..ec7ebc0c0d 100644 --- a/packages/backend-next/src/index.ts +++ b/packages/backend-next/src/index.ts @@ -14,13 +14,11 @@ * limitations under the License. */ -import { createBackend } from '@backstage/backend-app-api'; import { catalogPlugin } from '@backstage/plugin-catalog-backend'; import { scaffolderCatalogModule } from '@backstage/plugin-scaffolder-backend'; +import { createBackend } from '@backstage/backend-defaults'; -const backend = createBackend({ - apis: [], -}); +const backend = createBackend(); backend.add(catalogPlugin({})); backend.add(scaffolderCatalogModule({})); diff --git a/packages/backend-plugin-api/CHANGELOG.md b/packages/backend-plugin-api/CHANGELOG.md index 30f00578fa..71987fd616 100644 --- a/packages/backend-plugin-api/CHANGELOG.md +++ b/packages/backend-plugin-api/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/backend-plugin-api +## 0.1.1 + +### Patch Changes + +- 0599732ec0: Refactored experimental backend system with new type names. +- 34c2f5aca1: The factory returned by `createBackendPlugin` and `createBackendModule` no longer require a parameter to be passed if the options are optional. +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-tasks@0.3.4 + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + +## 0.1.0 + +### Minor Changes + +- 91c1d12123: Introduced new package for creating backend plugins using the new alpha backend plugin framework. + This package is still considered **EXPERIMENTAL** and things will change without warning. Do not use this for production. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/backend-tasks@0.3.3 + ## 0.1.0-next.0 ### Minor Changes diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index df8474d670..01423390e6 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -17,32 +17,11 @@ import { TransportStreamOptions } from 'winston-transport'; import { UrlReader } from '@backstage/backend-common'; // @public (undocumented) -export type AnyServiceFactory = ServiceFactory< - unknown, - unknown, - { - [key in string]: unknown; - } ->; - -// @public (undocumented) -export interface BackendInitRegistry { +export interface BackendFeature { // (undocumented) - registerExtensionPoint( - ref: ServiceRef, - impl: TExtensionPoint, - ): void; + id: string; // (undocumented) - registerInit< - Deps extends { - [name in string]: unknown; - }, - >(options: { - deps: { - [name in keyof Deps]: ServiceRef; - }; - init: (deps: Deps) => Promise; - }): void; + register(reg: BackendRegistrationPoints): void; } // @public (undocumented) @@ -53,7 +32,7 @@ export interface BackendModuleConfig { pluginId: string; // (undocumented) register( - reg: Omit, + reg: Omit, options: TOptions, ): void; } @@ -63,15 +42,27 @@ export interface BackendPluginConfig { // (undocumented) id: string; // (undocumented) - register(reg: BackendInitRegistry, options: TOptions): void; + register(reg: BackendRegistrationPoints, options: TOptions): void; } // @public (undocumented) -export interface BackendRegistrable { +export interface BackendRegistrationPoints { // (undocumented) - id: string; + registerExtensionPoint( + ref: ExtensionPoint, + impl: TExtensionPoint, + ): void; // (undocumented) - register(reg: BackendInitRegistry): void; + registerInit< + Deps extends { + [name in string]: unknown; + }, + >(options: { + deps: { + [name in keyof Deps]: ServiceRef | ExtensionPoint; + }; + init(deps: Deps): Promise; + }): void; } // @public (undocumented) @@ -83,12 +74,16 @@ export const configServiceRef: ServiceRef; // @public (undocumented) export function createBackendModule( config: BackendModuleConfig, -): (option: TOptions) => BackendRegistrable; +): undefined extends TOptions + ? (options?: TOptions) => BackendFeature + : (options: TOptions) => BackendFeature; // @public (undocumented) export function createBackendPlugin( config: BackendPluginConfig, -): (option: TOptions) => BackendRegistrable; +): undefined extends TOptions + ? (options?: TOptions) => BackendFeature + : (options: TOptions) => BackendFeature; // @public (undocumented) export function createExtensionPoint(options: { @@ -97,15 +92,22 @@ export function createExtensionPoint(options: { // @public (undocumented) export function createServiceFactory< - Api, - Impl extends Api, - Deps extends { + TService, + TImpl extends TService, + TDeps extends { [name in string]: unknown; }, ->(factory: ServiceFactory): ServiceFactory; +>(factory: { + service: ServiceRef; + deps: TypesToServiceRef; + factory(deps: DepsToDepFactories): Promise>; +}): ServiceFactory; // @public (undocumented) -export function createServiceRef(options: { id: string }): ServiceRef; +export function createServiceRef(options: { + id: string; + defaultFactory?: (service: ServiceRef) => Promise>; +}): ServiceRef; // @public (undocumented) export const databaseServiceRef: ServiceRef; @@ -164,22 +166,21 @@ export const permissionsServiceRef: ServiceRef< export const schedulerServiceRef: ServiceRef; // @public (undocumented) -export type ServiceFactory< - TApi, - TImpl extends TApi, - TDeps extends { - [name in string]: unknown; - }, -> = { - service: ServiceRef; - deps: TypesToServiceRef; - factory(deps: DepsToDepFactories): Promise>; +export type ServiceFactory = { + service: ServiceRef; + deps: { + [key in string]: ServiceRef; + }; + factory(deps: { + [key in string]: unknown; + }): Promise>; }; // @public export type ServiceRef = { id: string; T: T; + defaultFactory?: (service: ServiceRef) => Promise>; toString(): string; $$ref: 'service'; }; diff --git a/packages/backend-plugin-api/package.json b/packages/backend-plugin-api/package.json index 9f3aa255bf..9a4e9ce8a8 100644 --- a/packages/backend-plugin-api/package.json +++ b/packages/backend-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-plugin-api", "description": "Core API used by Backstage backend plugins", - "version": "0.1.0-next.0", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -35,16 +35,16 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/plugin-permission-common": "^0.6.3-next.1", - "@backstage/backend-tasks": "^0.3.3-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/plugin-permission-common": "^0.6.3", + "@backstage/backend-tasks": "^0.3.4", "@types/express": "^4.17.6", "express": "^4.17.1", "winston": "^3.2.1", "winston-transport": "^4.5.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3" + "@backstage/cli": "^0.18.1" }, "files": [ "dist", diff --git a/packages/backend-plugin-api/src/services/system/index.ts b/packages/backend-plugin-api/src/services/system/index.ts index eead2297a5..817b0a590f 100644 --- a/packages/backend-plugin-api/src/services/system/index.ts +++ b/packages/backend-plugin-api/src/services/system/index.ts @@ -20,6 +20,5 @@ export type { DepsToDepFactories, FactoryFunc, ServiceFactory, - AnyServiceFactory, } from './types'; export { createServiceRef, createServiceFactory } from './types'; diff --git a/packages/backend-plugin-api/src/services/system/types.ts b/packages/backend-plugin-api/src/services/system/types.ts index d578434170..3d6ebfc0dd 100644 --- a/packages/backend-plugin-api/src/services/system/types.ts +++ b/packages/backend-plugin-api/src/services/system/types.ts @@ -28,6 +28,12 @@ export type ServiceRef = { */ T: T; + /** + * The default factory that will be used to create service + * instances if no other factory is provided. + */ + defaultFactory?: (service: ServiceRef) => Promise>; + toString(): string; $$ref: 'service'; @@ -45,32 +51,26 @@ export type DepsToDepFactories = { export type FactoryFunc = (pluginId: string) => Promise; /** @public */ -export type ServiceFactory< - TApi, - TImpl extends TApi, - TDeps extends { [name in string]: unknown }, -> = { - service: ServiceRef; - deps: TypesToServiceRef; - factory(deps: DepsToDepFactories): Promise>; +export type ServiceFactory = { + service: ServiceRef; + deps: { [key in string]: ServiceRef }; + factory(deps: { [key in string]: unknown }): Promise>; }; -/** @public */ -export type AnyServiceFactory = ServiceFactory< - unknown, - unknown, - { [key in string]: unknown } ->; - /** * @public */ -export function createServiceRef(options: { id: string }): ServiceRef { +export function createServiceRef(options: { + id: string; + defaultFactory?: (service: ServiceRef) => Promise>; +}): ServiceRef { + const { id, defaultFactory } = options; return { - id: options.id, + id, get T(): T { throw new Error(`tried to read ServiceRef.T of ${this}`); }, + defaultFactory, toString() { return `serviceRef{${options.id}}`; }, @@ -82,9 +82,13 @@ export function createServiceRef(options: { id: string }): ServiceRef { * @public */ export function createServiceFactory< - Api, - Impl extends Api, - Deps extends { [name in string]: unknown }, ->(factory: ServiceFactory): ServiceFactory { - return factory; + TService, + TImpl extends TService, + TDeps extends { [name in string]: unknown }, +>(factory: { + service: ServiceRef; + deps: TypesToServiceRef; + factory(deps: DepsToDepFactories): Promise>; +}): ServiceFactory { + return factory as ServiceFactory; } diff --git a/packages/backend-plugin-api/src/wiring/factories.test.ts b/packages/backend-plugin-api/src/wiring/factories.test.ts new file mode 100644 index 0000000000..6cfcdd06cc --- /dev/null +++ b/packages/backend-plugin-api/src/wiring/factories.test.ts @@ -0,0 +1,89 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + createBackendPlugin, + createExtensionPoint, +} from './factories'; + +describe('createExtensionPoint', () => { + it('should create an ExtensionPoint', () => { + const extensionPoint = createExtensionPoint({ id: 'x' }); + expect(extensionPoint).toBeDefined(); + expect(extensionPoint.id).toBe('x'); + expect(() => extensionPoint.T).toThrow(); + expect(String(extensionPoint)).toBe('extensionPoint{x}'); + }); +}); + +describe('createBackendPlugin', () => { + it('should create an BackendPlugin', () => { + const plugin = createBackendPlugin({ + id: 'x', + register(_reg, _options: { a: string }) {}, + }); + expect(plugin).toBeDefined(); + expect(plugin({ a: 'a' })).toBeDefined(); + expect(plugin({ a: 'a' }).id).toBe('x'); + // @ts-expect-error + expect(plugin()).toBeDefined(); + // @ts-expect-error + expect(plugin({ b: 'b' })).toBeDefined(); + }); + + it('should create plugins with optional options', () => { + const plugin = createBackendPlugin({ + id: 'x', + register(_reg, _options?: { a: string }) {}, + }); + expect(plugin).toBeDefined(); + expect(plugin({ a: 'a' })).toBeDefined(); + expect(plugin()).toBeDefined(); + // @ts-expect-error + expect(plugin({ b: 'b' })).toBeDefined(); + }); +}); + +describe('createBackendModule', () => { + it('should create an BackendModule', () => { + const mod = createBackendModule({ + pluginId: 'x', + moduleId: 'y', + register(_reg, _options: { a: string }) {}, + }); + expect(mod).toBeDefined(); + expect(mod({ a: 'a' })).toBeDefined(); + expect(mod({ a: 'a' }).id).toBe('x.y'); + // @ts-expect-error + expect(mod()).toBeDefined(); + // @ts-expect-error + expect(mod({ b: 'b' })).toBeDefined(); + }); + + it('should create modules with optional options', () => { + const mod = createBackendModule({ + pluginId: 'x', + moduleId: 'y', + register(_reg, _options?: { a: string }) {}, + }); + expect(mod).toBeDefined(); + expect(mod({ a: 'a' })).toBeDefined(); + expect(mod()).toBeDefined(); + // @ts-expect-error + expect(mod({ b: 'b' })).toBeDefined(); + }); +}); diff --git a/packages/backend-plugin-api/src/wiring/factories.ts b/packages/backend-plugin-api/src/wiring/factories.ts new file mode 100644 index 0000000000..68f13f6c30 --- /dev/null +++ b/packages/backend-plugin-api/src/wiring/factories.ts @@ -0,0 +1,82 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + BackendRegistrationPoints, + BackendFeature, + ExtensionPoint, +} from './types'; + +/** @public */ +export function createExtensionPoint(options: { + id: string; +}): ExtensionPoint { + return { + id: options.id, + get T(): T { + throw new Error(`tried to read ExtensionPoint.T of ${this}`); + }, + toString() { + return `extensionPoint{${options.id}}`; + }, + $$ref: 'extension-point', // TODO: declare + }; +} + +/** @public */ +export interface BackendPluginConfig { + id: string; + register(reg: BackendRegistrationPoints, options: TOptions): void; +} + +/** @public */ +export function createBackendPlugin( + config: BackendPluginConfig, +): undefined extends TOptions + ? (options?: TOptions) => BackendFeature + : (options: TOptions) => BackendFeature { + return (options?: TOptions) => ({ + id: config.id, + register(register: BackendRegistrationPoints) { + return config.register(register, options!); + }, + }); +} + +/** @public */ +export interface BackendModuleConfig { + pluginId: string; + moduleId: string; + register( + reg: Omit, + options: TOptions, + ): void; +} + +/** @public */ +export function createBackendModule( + config: BackendModuleConfig, +): undefined extends TOptions + ? (options?: TOptions) => BackendFeature + : (options: TOptions) => BackendFeature { + return (options?: TOptions) => ({ + id: `${config.pluginId}.${config.moduleId}`, + register(register: BackendRegistrationPoints) { + // TODO: Hide registerExtensionPoint + return config.register(register, options!); + }, + }); +} diff --git a/packages/backend-plugin-api/src/wiring/index.ts b/packages/backend-plugin-api/src/wiring/index.ts index 9340dc8fa9..8f85edb2eb 100644 --- a/packages/backend-plugin-api/src/wiring/index.ts +++ b/packages/backend-plugin-api/src/wiring/index.ts @@ -14,5 +14,14 @@ * limitations under the License. */ -export type { BackendRegistrable } from './types'; -export * from './types'; +export type { BackendModuleConfig, BackendPluginConfig } from './factories'; +export { + createBackendModule, + createBackendPlugin, + createExtensionPoint, +} from './factories'; +export type { + BackendRegistrationPoints, + BackendFeature, + ExtensionPoint, +} from './types'; diff --git a/packages/backend-plugin-api/src/wiring/types.ts b/packages/backend-plugin-api/src/wiring/types.ts index 2b0bef16f7..cdb56ea2e4 100644 --- a/packages/backend-plugin-api/src/wiring/types.ts +++ b/packages/backend-plugin-api/src/wiring/types.ts @@ -36,78 +36,22 @@ export type ExtensionPoint = { }; /** @public */ -export function createExtensionPoint(options: { - id: string; -}): ExtensionPoint { - return { - id: options.id, - get T(): T { - throw new Error(`tried to read ExtensionPoint.T of ${this}`); - }, - toString() { - return `extensionPoint{${options.id}}`; - }, - $$ref: 'extension-point', // TODO: declare - }; -} - -/** @public */ -export interface BackendInitRegistry { +export interface BackendRegistrationPoints { registerExtensionPoint( - ref: ServiceRef, + ref: ExtensionPoint, impl: TExtensionPoint, ): void; registerInit(options: { - deps: { [name in keyof Deps]: ServiceRef }; - init: (deps: Deps) => Promise; + deps: { + [name in keyof Deps]: ServiceRef | ExtensionPoint; + }; + init(deps: Deps): Promise; }): void; } /** @public */ -export interface BackendRegistrable { +export interface BackendFeature { + // TODO(Rugvip): Try to get rid of the ID at this level, allowing for a feature to register multiple features as a bundle id: string; - register(reg: BackendInitRegistry): void; -} - -/** @public */ -export interface BackendPluginConfig { - id: string; - register(reg: BackendInitRegistry, options: TOptions): void; -} - -// TODO: Make option optional in the returned factory if they are indeed optional -/** @public */ -export function createBackendPlugin( - config: BackendPluginConfig, -): (option: TOptions) => BackendRegistrable { - return options => ({ - id: config.id, - register(register) { - return config.register(register, options); - }, - }); -} - -/** @public */ -export interface BackendModuleConfig { - pluginId: string; - moduleId: string; - register( - reg: Omit, - options: TOptions, - ): void; -} - -// TODO: Make option optional in the returned factory if they are indeed optional -/** @public */ -export function createBackendModule( - config: BackendModuleConfig, -): (option: TOptions) => BackendRegistrable { - return options => ({ - id: `${config.pluginId}.${config.moduleId}`, - register(register) { - // TODO: Hide registerExtensionPoint - return config.register(register, options); - }, - }); + register(reg: BackendRegistrationPoints): void; } diff --git a/packages/backend-tasks/CHANGELOG.md b/packages/backend-tasks/CHANGELOG.md index e7fa4e6eeb..59e5c8ca8a 100644 --- a/packages/backend-tasks/CHANGELOG.md +++ b/packages/backend-tasks/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/backend-tasks +## 0.3.4 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## 0.3.4-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## 0.3.3 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/errors@1.1.0 + ## 0.3.3-next.3 ### Patch Changes diff --git a/packages/backend-tasks/package.json b/packages/backend-tasks/package.json index 4f5e91e186..7d8886d77b 100644 --- a/packages/backend-tasks/package.json +++ b/packages/backend-tasks/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/backend-tasks", "description": "Common distributed task management library for Backstage backends", - "version": "0.3.3-next.3", + "version": "0.3.4", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -33,11 +33,11 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", + "@backstage/backend-common": "^0.15.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", + "@backstage/errors": "^1.1.0", "@backstage/types": "^1.0.0", - "@types/luxon": "^2.0.4", + "@types/luxon": "^3.0.0", "cron": "^2.0.0", "knex": "^2.0.0", "lodash": "^4.17.21", @@ -48,8 +48,8 @@ "zod": "^3.9.5" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "@types/cron": "^2.0.0", "wait-for-expect": "^3.0.2" }, diff --git a/packages/backend-tasks/src/tasks/TaskScheduler.ts b/packages/backend-tasks/src/tasks/TaskScheduler.ts index f1668a6691..f14fb9fc2b 100644 --- a/packages/backend-tasks/src/tasks/TaskScheduler.ts +++ b/packages/backend-tasks/src/tasks/TaskScheduler.ts @@ -58,9 +58,12 @@ export class TaskScheduler { */ forPlugin(pluginId: string): PluginTaskScheduler { const databaseFactory = once(async () => { - const knex = await this.databaseManager.forPlugin(pluginId).getClient(); + const databaseManager = this.databaseManager.forPlugin(pluginId); + const knex = await databaseManager.getClient(); - await migrateBackendTasks(knex); + if (!databaseManager.migrations?.skip) { + await migrateBackendTasks(knex); + } const janitor = new PluginTaskSchedulerJanitor({ knex, diff --git a/packages/backend-tasks/src/tasks/TaskWorker.ts b/packages/backend-tasks/src/tasks/TaskWorker.ts index c99c08e4fb..f56c03c3d5 100644 --- a/packages/backend-tasks/src/tasks/TaskWorker.ts +++ b/packages/backend-tasks/src/tasks/TaskWorker.ts @@ -292,14 +292,21 @@ export class TaskWorker { seconds: dt, })}`, ); - nextRun = this.knex.client.config.client.includes('sqlite3') - ? this.knex.raw( - `max(datetime(next_run_start_at, ?), datetime('now'))`, - [`+${dt} seconds`], - ) - : this.knex.raw( - `greatest(next_run_start_at + interval '${dt} seconds', now())`, - ); + + if (this.knex.client.config.client.includes('sqlite3')) { + nextRun = this.knex.raw( + `max(datetime(next_run_start_at, ?), datetime('now'))`, + [`+${dt} seconds`], + ); + } else if (this.knex.client.config.client.includes('mysql')) { + nextRun = this.knex.raw( + `greatest(next_run_start_at + interval ${dt} second, now())`, + ); + } else { + nextRun = this.knex.raw( + `greatest(next_run_start_at + interval '${dt} seconds', now())`, + ); + } } const rows = await this.knex(DB_TASKS_TABLE) diff --git a/packages/backend-tasks/src/tasks/util.test.ts b/packages/backend-tasks/src/tasks/util.test.ts index 614de8c6c8..ceeeba14d6 100644 --- a/packages/backend-tasks/src/tasks/util.test.ts +++ b/packages/backend-tasks/src/tasks/util.test.ts @@ -14,9 +14,16 @@ * limitations under the License. */ +import knexFactory, { Knex } from 'knex'; import { Duration } from 'luxon'; import { AbortController } from 'node-abort-controller'; -import { delegateAbortController, sleep, validateId } from './util'; +import { delegateAbortController, nowPlus, sleep, validateId } from './util'; + +class KnexBuilder { + public build(client: string): Knex { + return knexFactory({ client }); + } +} describe('util', () => { describe('validateId', () => { @@ -73,4 +80,35 @@ describe('util', () => { expect(child.signal.aborted).toBe(true); }); }); + + describe('nowPlus', () => { + describe('without duration', () => { + const databases = [ + { client: 'sqlite3', expected: 'CURRENT_TIMESTAMP' }, + { client: 'mysql2', expected: 'CURRENT_TIMESTAMP' }, + { client: 'pg', expected: 'CURRENT_TIMESTAMP' }, + ]; + + it.each(databases)('for client $client', ({ client, expected }) => { + const knex = new KnexBuilder().build(client); + const result = nowPlus(undefined, knex); + + expect(result.toString()).toBe(expected); + }); + }); + describe('With duration', () => { + const databases = [ + { client: 'sqlite3', expected: "datetime('now', '20 seconds')" }, + { client: 'mysql2', expected: 'now() + interval 20 second' }, + { client: 'pg', expected: "now() + interval '20 seconds'" }, + ]; + it.each(databases)('for client $client', ({ client, expected }) => { + const duration = Duration.fromObject({ seconds: 20 }); + const knex = new KnexBuilder().build(client); + const result = nowPlus(duration, knex); + + expect(result.toString()).toBe(expected); + }); + }); + }); }); diff --git a/packages/backend-tasks/src/tasks/util.ts b/packages/backend-tasks/src/tasks/util.ts index 34280cc2d4..2561203318 100644 --- a/packages/backend-tasks/src/tasks/util.ts +++ b/packages/backend-tasks/src/tasks/util.ts @@ -38,9 +38,16 @@ export function nowPlus(duration: Duration | undefined, knex: Knex) { if (!seconds) { return knex.fn.now(); } - return knex.client.config.client.includes('sqlite3') - ? knex.raw(`datetime('now', ?)`, [`${seconds} seconds`]) - : knex.raw(`now() + interval '${seconds} seconds'`); + + if (knex.client.config.client.includes('sqlite3')) { + return knex.raw(`datetime('now', ?)`, [`${seconds} seconds`]); + } + + if (knex.client.config.client.includes('mysql')) { + return knex.raw(`now() + interval ${seconds} second`); + } + + return knex.raw(`now() + interval '${seconds} seconds'`); } /** diff --git a/packages/backend-test-utils/CHANGELOG.md b/packages/backend-test-utils/CHANGELOG.md index 46ba178820..2e1b1bea6a 100644 --- a/packages/backend-test-utils/CHANGELOG.md +++ b/packages/backend-test-utils/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/backend-test-utils +## 0.1.27 + +### Patch Changes + +- 0599732ec0: Refactored experimental backend system with new type names. +- 56e1b4b89c: Added alpha test helpers for the new experimental backend system. +- Updated dependencies + - @backstage/cli@0.18.1 + - @backstage/backend-common@0.15.0 + - @backstage/backend-app-api@0.2.0 + - @backstage/backend-plugin-api@0.1.1 + +## 0.1.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/cli@0.18.1-next.0 + +## 0.1.26 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/cli@0.18.0 + ## 0.1.26-next.3 ### Patch Changes diff --git a/packages/backend-test-utils/api-report.md b/packages/backend-test-utils/api-report.md index cba8953432..c0f6a43321 100644 --- a/packages/backend-test-utils/api-report.md +++ b/packages/backend-test-utils/api-report.md @@ -3,7 +3,11 @@ > 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 { ExtensionPoint } from '@backstage/backend-plugin-api'; import { Knex } from 'knex'; +import { ServiceFactory } from '@backstage/backend-plugin-api'; +import { ServiceRef } from '@backstage/backend-plugin-api'; // @public (undocumented) export function isDockerDisabledForTests(): boolean; @@ -15,6 +19,38 @@ export function setupRequestMockHandlers(worker: { resetHandlers: () => void; }): void; +// @alpha (undocumented) +export function startTestBackend< + TServices extends any[], + TExtensionPoints extends any[], +>(options: TestBackendOptions): Promise; + +// @alpha (undocumented) +export interface TestBackendOptions< + TServices extends any[], + TExtensionPoints extends any[], +> { + // (undocumented) + extensionPoints?: readonly [ + ...{ + [index in keyof TExtensionPoints]: [ + ExtensionPoint, + Partial, + ]; + }, + ]; + // (undocumented) + features?: BackendFeature[]; + // (undocumented) + services?: readonly [ + ...{ + [index in keyof TServices]: + | ServiceFactory + | [ServiceRef, Partial]; + }, + ]; +} + // @public export type TestDatabaseId = | 'POSTGRES_13' diff --git a/packages/backend-test-utils/package.json b/packages/backend-test-utils/package.json index 3003dca281..28baf725bd 100644 --- a/packages/backend-test-utils/package.json +++ b/packages/backend-test-utils/package.json @@ -1,14 +1,15 @@ { "name": "@backstage/backend-test-utils", "description": "Test helpers library for Backstage backends", - "version": "0.1.26-next.3", + "version": "0.1.27", "main": "src/index.ts", "types": "src/index.ts", "private": false, "publishConfig": { "access": "public", "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "types": "dist/index.d.ts", + "alphaTypes": "dist/index.alpha.d.ts" }, "backstage": { "role": "node-library" @@ -25,7 +26,7 @@ ], "license": "Apache-2.0", "scripts": { - "build": "backstage-cli package build", + "build": "backstage-cli package build --experimental-type-build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -34,21 +35,24 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-app-api": "^0.2.0", + "@backstage/backend-plugin-api": "^0.1.1", + "@backstage/cli": "^0.18.1", "@backstage/config": "^1.0.1", "better-sqlite3": "^7.5.0", "knex": "^2.0.0", - "msw": "^0.44.0", + "msw": "^0.45.0", "mysql2": "^2.2.5", "pg": "^8.3.0", "testcontainers": "^8.1.2", "uuid": "^8.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3" + "@backstage/cli": "^0.18.1" }, "files": [ - "dist" + "dist", + "alpha" ] } diff --git a/packages/backend-test-utils/src/index.ts b/packages/backend-test-utils/src/index.ts index 5fef4e6b55..ae937d2fc8 100644 --- a/packages/backend-test-utils/src/index.ts +++ b/packages/backend-test-utils/src/index.ts @@ -22,4 +22,5 @@ export * from './database'; export * from './msw'; +export * from './next'; export * from './util'; diff --git a/plugins/search/src/components/LegacySearchPage/index.ts b/packages/backend-test-utils/src/next/index.ts similarity index 85% rename from plugins/search/src/components/LegacySearchPage/index.ts rename to packages/backend-test-utils/src/next/index.ts index 5b64054f8d..9bb5431772 100644 --- a/plugins/search/src/components/LegacySearchPage/index.ts +++ b/packages/backend-test-utils/src/next/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * Copyright 2022 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,4 +14,4 @@ * limitations under the License. */ -export { LegacySearchPage } from './LegacySearchPage'; +export * from './wiring'; diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts new file mode 100644 index 0000000000..488a258388 --- /dev/null +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.test.ts @@ -0,0 +1,97 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + createExtensionPoint, + createServiceFactory, + createServiceRef, +} from '@backstage/backend-plugin-api'; +import { startTestBackend } from './TestBackend'; + +describe('TestBackend', () => { + it('should get a type error if service implementation does not match', async () => { + type Obj = { a: string; b: string }; + const serviceRef = createServiceRef({ id: 'a' }); + const extensionPoint1 = createExtensionPoint({ id: 'b1' }); + const extensionPoint2 = createExtensionPoint({ id: 'b2' }); + const extensionPoint3 = createExtensionPoint({ id: 'b3' }); + const extensionPoint4 = createExtensionPoint({ id: 'b4' }); + const extensionPoint5 = createExtensionPoint({ id: 'b5' }); + await startTestBackend({ + services: [ + // @ts-expect-error + [extensionPoint1, { a: 'a' }], + [serviceRef, { a: 'a' }], + [serviceRef, { a: 'a', b: 'b' }], + // @ts-expect-error + [serviceRef, { c: 'c' }], + // @ts-expect-error + [serviceRef, { a: 'a', c: 'c' }], + // @ts-expect-error + [serviceRef, { a: 'a', b: 'b', c: 'c' }], + ], + extensionPoints: [ + // @ts-expect-error + [serviceRef, { a: 'a' }], + [extensionPoint1, { a: 'a' }], + [extensionPoint2, { a: 'a', b: 'b' }], + // @ts-expect-error + [extensionPoint3, { c: 'c' }], + // @ts-expect-error + [extensionPoint4, { a: 'a', c: 'c' }], + // @ts-expect-error + [extensionPoint5, { a: 'a', b: 'b', c: 'c' }], + ], + }); + expect(1).toBe(1); + }); + + it('should start the test backend', async () => { + const testRef = createServiceRef<(v: string) => void>({ id: 'test' }); + const testFn = jest.fn(); + + const sf = createServiceFactory({ + deps: {}, + service: testRef, + factory: async () => { + return async () => testFn; + }, + }); + + const testModule = createBackendModule({ + moduleId: 'test.module', + pluginId: 'test', + register(env) { + env.registerInit({ + deps: { + test: testRef, + }, + async init({ test }) { + test('winning'); + }, + }); + }, + }); + + await startTestBackend({ + services: [sf], + features: [testModule({})], + }); + + expect(testFn).toBeCalledWith('winning'); + }); +}); diff --git a/packages/backend-test-utils/src/next/wiring/TestBackend.ts b/packages/backend-test-utils/src/next/wiring/TestBackend.ts new file mode 100644 index 0000000000..98e979793e --- /dev/null +++ b/packages/backend-test-utils/src/next/wiring/TestBackend.ts @@ -0,0 +1,95 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createSpecializedBackend } from '@backstage/backend-app-api'; +import { + ServiceFactory, + ServiceRef, + createServiceFactory, + BackendFeature, + ExtensionPoint, +} from '@backstage/backend-plugin-api'; + +/** @alpha */ +export interface TestBackendOptions< + TServices extends any[], + TExtensionPoints extends any[], +> { + services?: readonly [ + ...{ + [index in keyof TServices]: + | ServiceFactory + | [ServiceRef, Partial]; + }, + ]; + extensionPoints?: readonly [ + ...{ + [index in keyof TExtensionPoints]: [ + ExtensionPoint, + Partial, + ]; + }, + ]; + features?: BackendFeature[]; +} + +/** @alpha */ +export async function startTestBackend< + TServices extends any[], + TExtensionPoints extends any[], +>(options: TestBackendOptions): Promise { + const { + services = [], + extensionPoints = [], + features = [], + ...otherOptions + } = options; + + const factories = services.map(serviceDef => { + if (Array.isArray(serviceDef)) { + // if type is ExtensionPoint? + // do something differently? + return createServiceFactory({ + service: serviceDef[0], + deps: {}, + factory: async () => async () => serviceDef[1], + }); + } + return serviceDef as ServiceFactory; + }); + + const backend = createSpecializedBackend({ + ...otherOptions, + services: factories, + }); + + backend.add({ + id: `---test-extension-point-registrar`, + register(reg) { + for (const [ref, impl] of extensionPoints) { + reg.registerExtensionPoint(ref, impl); + } + + reg.registerInit({ deps: {}, async init() {} }); + }, + }); + + for (const feature of features) { + backend.add(feature); + } + + await backend.start(); +} diff --git a/plugins/search/src/components/SearchBar/index.tsx b/packages/backend-test-utils/src/next/wiring/index.ts similarity index 77% rename from plugins/search/src/components/SearchBar/index.tsx rename to packages/backend-test-utils/src/next/wiring/index.ts index f95d2ec0fc..eb7b773e33 100644 --- a/plugins/search/src/components/SearchBar/index.tsx +++ b/packages/backend-test-utils/src/next/wiring/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * Copyright 2022 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,5 +14,5 @@ * limitations under the License. */ -export { SearchBar, SearchBarBase } from './SearchBar'; -export type { SearchBarProps, SearchBarBaseProps } from './SearchBar'; +export { startTestBackend } from './TestBackend'; +export type { TestBackendOptions } from './TestBackend'; diff --git a/packages/backend/CHANGELOG.md b/packages/backend/CHANGELOG.md index c38a16c86f..670ce31973 100644 --- a/packages/backend/CHANGELOG.md +++ b/packages/backend/CHANGELOG.md @@ -1,5 +1,117 @@ # example-backend +## 0.2.74 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-kubernetes-backend@0.7.1 + - @backstage/integration@1.3.0 + - @backstage/plugin-scaffolder-backend@1.5.0 + - @backstage/plugin-auth-backend@0.15.1 + - @backstage/plugin-graphql-backend@0.1.25 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-tech-insights-node@0.3.3 + - @backstage/plugin-catalog-backend@1.3.1 + - example-app@0.2.74 + - @backstage/plugin-app-backend@0.3.35 + - @backstage/plugin-auth-node@0.2.4 + - @backstage/plugin-azure-devops-backend@0.3.14 + - @backstage/plugin-badges-backend@0.1.29 + - @backstage/plugin-code-coverage-backend@0.2.1 + - @backstage/plugin-jenkins-backend@0.1.25 + - @backstage/plugin-kafka-backend@0.2.28 + - @backstage/plugin-permission-backend@0.5.10 + - @backstage/plugin-permission-node@0.6.4 + - @backstage/plugin-proxy-backend@0.2.29 + - @backstage/plugin-rollbar-backend@0.1.32 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.3 + - @backstage/plugin-search-backend@1.0.1 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.1 + - @backstage/plugin-search-backend-module-pg@0.3.6 + - @backstage/plugin-search-backend-node@1.0.1 + - @backstage/plugin-tech-insights-backend@0.5.1 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.19 + - @backstage/plugin-techdocs-backend@1.2.1 + - @backstage/plugin-todo-backend@0.1.32 + +## 0.2.74-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-scaffolder-backend@1.5.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-kubernetes-backend@0.7.1-next.0 + - @backstage/plugin-tech-insights-node@0.3.3-next.0 + - @backstage/plugin-app-backend@0.3.35-next.0 + - @backstage/plugin-auth-backend@0.15.1-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 + - @backstage/plugin-azure-devops-backend@0.3.14-next.0 + - @backstage/plugin-badges-backend@0.1.29-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + - @backstage/plugin-code-coverage-backend@0.2.1-next.0 + - @backstage/plugin-graphql-backend@0.1.25-next.0 + - @backstage/plugin-jenkins-backend@0.1.25-next.0 + - @backstage/plugin-kafka-backend@0.2.28-next.0 + - @backstage/plugin-permission-backend@0.5.10-next.0 + - @backstage/plugin-permission-node@0.6.4-next.0 + - @backstage/plugin-proxy-backend@0.2.29-next.0 + - @backstage/plugin-rollbar-backend@0.1.32-next.0 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.3-next.0 + - @backstage/plugin-search-backend@1.0.1-next.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.1-next.0 + - @backstage/plugin-search-backend-module-pg@0.3.6-next.0 + - @backstage/plugin-search-backend-node@1.0.1-next.0 + - @backstage/plugin-tech-insights-backend@0.5.1-next.0 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.19-next.0 + - @backstage/plugin-techdocs-backend@1.2.1-next.0 + - @backstage/plugin-todo-backend@0.1.32-next.0 + - example-app@0.2.74-next.0 + +## 0.2.73 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-code-coverage-backend@0.2.0 + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/plugin-tech-insights-backend@0.5.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-kubernetes-backend@0.7.0 + - @backstage/plugin-search-backend@1.0.0 + - @backstage/plugin-search-backend-node@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/plugin-search-backend-module-elasticsearch@1.0.0 + - @backstage/plugin-scaffolder-backend@1.4.0 + - @backstage/plugin-auth-backend@0.15.0 + - @backstage/plugin-jenkins-backend@0.1.24 + - @backstage/plugin-proxy-backend@0.2.28 + - @backstage/plugin-search-backend-module-pg@0.3.5 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-app-backend@0.3.34 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/plugin-azure-devops-backend@0.3.13 + - @backstage/plugin-graphql-backend@0.1.24 + - @backstage/plugin-permission-backend@0.5.9 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/plugin-permission-node@0.6.3 + - @backstage/plugin-rollbar-backend@0.1.31 + - @backstage/plugin-techdocs-backend@1.2.0 + - @backstage/plugin-todo-backend@0.1.31 + - @backstage/backend-tasks@0.3.3 + - @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.18 + - @backstage/plugin-tech-insights-node@0.3.2 + - @backstage/plugin-kafka-backend@0.2.27 + - @backstage/plugin-badges-backend@0.1.28 + - example-app@0.2.73 + - @backstage/plugin-scaffolder-backend-module-rails@0.4.2 + ## 0.2.73-next.3 ### Patch Changes diff --git a/packages/backend/Dockerfile b/packages/backend/Dockerfile index 86f6e17861..ed18da530b 100644 --- a/packages/backend/Dockerfile +++ b/packages/backend/Dockerfile @@ -11,24 +11,30 @@ FROM node:16-bullseye-slim -WORKDIR /app - -# install sqlite3 dependencies, you can skip this if you don't use sqlite3 in the image +# Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, +# in which case you should also move better-sqlite3 to "devDependencies" in package.json. RUN apt-get update && \ apt-get install -y --no-install-recommends libsqlite3-dev python3 build-essential && \ rm -rf /var/lib/apt/lists/* && \ yarn config set python /usr/bin/python3 +# From here on we use the least-privileged `node` user to run the backend. +USER node +WORKDIR /app + +# This switches many Node.js dependencies to production mode. +ENV NODE_ENV production + # Copy repo skeleton first, to avoid unnecessary docker cache invalidation. # The skeleton contains the package.json of each package in the monorepo, # and along with yarn.lock and the root package.json, that's enough to run yarn install. -COPY yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./ +COPY --chown=node:node yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./ RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz RUN yarn install --frozen-lockfile --production --network-timeout 300000 && rm -rf "$(yarn cache dir)" # Then copy the rest of the backend bundle, along with any other files we might want. -COPY packages/backend/dist/bundle.tar.gz app-config.yaml ./ +COPY --chown=node:node packages/backend/dist/bundle.tar.gz app-config*.yaml ./ RUN tar xzf bundle.tar.gz && rm bundle.tar.gz CMD ["node", "packages/backend", "--config", "app-config.yaml"] diff --git a/packages/backend/package.json b/packages/backend/package.json index 67070bfeee..5226cf3270 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,6 +1,6 @@ { "name": "example-backend", - "version": "0.2.73-next.3", + "version": "0.2.74", "main": "dist/index.cjs.js", "types": "src/index.ts", "license": "Apache-2.0", @@ -26,39 +26,40 @@ "build-image": "docker build ../.. -f Dockerfile --tag example-backend" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/backend-tasks": "^0.3.3-next.3", - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-tasks": "^0.3.4", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-app-backend": "^0.3.34-next.3", - "@backstage/plugin-auth-backend": "^0.15.0-next.3", - "@backstage/plugin-auth-node": "^0.2.3-next.2", - "@backstage/plugin-azure-devops-backend": "^0.3.13-next.1", - "@backstage/plugin-badges-backend": "^0.1.28-next.2", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", - "@backstage/plugin-code-coverage-backend": "^0.2.0-next.3", - "@backstage/plugin-graphql-backend": "^0.1.24-next.1", - "@backstage/plugin-jenkins-backend": "^0.1.24-next.3", - "@backstage/plugin-kubernetes-backend": "^0.7.0-next.3", - "@backstage/plugin-kafka-backend": "^0.2.27-next.2", - "@backstage/plugin-permission-backend": "^0.5.9-next.2", - "@backstage/plugin-permission-common": "^0.6.3-next.1", - "@backstage/plugin-permission-node": "^0.6.3-next.2", - "@backstage/plugin-proxy-backend": "^0.2.28-next.1", - "@backstage/plugin-rollbar-backend": "^0.1.31-next.1", - "@backstage/plugin-scaffolder-backend": "^1.4.0-next.3", - "@backstage/plugin-scaffolder-backend-module-rails": "^0.4.2-next.1", - "@backstage/plugin-search-backend": "^0.5.4-next.2", - "@backstage/plugin-search-backend-node": "^0.6.3-next.2", - "@backstage/plugin-search-backend-module-elasticsearch": "^0.2.0-next.2", - "@backstage/plugin-search-backend-module-pg": "^0.3.5-next.2", - "@backstage/plugin-techdocs-backend": "^1.2.0-next.3", - "@backstage/plugin-tech-insights-backend": "^0.5.0-next.3", - "@backstage/plugin-tech-insights-node": "^0.3.2-next.1", - "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.18-next.2", - "@backstage/plugin-todo-backend": "^0.1.31-next.2", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-app-backend": "^0.3.35", + "@backstage/plugin-auth-backend": "^0.15.1", + "@backstage/plugin-auth-node": "^0.2.4", + "@backstage/plugin-azure-devops-backend": "^0.3.14", + "@backstage/plugin-badges-backend": "^0.1.29", + "@backstage/plugin-catalog-backend": "^1.3.1", + "@backstage/plugin-code-coverage-backend": "^0.2.1", + "@backstage/plugin-graphql-backend": "^0.1.25", + "@backstage/plugin-jenkins-backend": "^0.1.25", + "@backstage/plugin-kubernetes-backend": "^0.7.1", + "@backstage/plugin-kafka-backend": "^0.2.28", + "@backstage/plugin-permission-backend": "^0.5.10", + "@backstage/plugin-permission-common": "^0.6.3", + "@backstage/plugin-permission-node": "^0.6.4", + "@backstage/plugin-proxy-backend": "^0.2.29", + "@backstage/plugin-rollbar-backend": "^0.1.32", + "@backstage/plugin-scaffolder-backend": "^1.5.0", + "@backstage/plugin-scaffolder-backend-module-rails": "^0.4.3", + "@backstage/plugin-search-backend": "^1.0.1", + "@backstage/plugin-search-common": "^1.0.0", + "@backstage/plugin-search-backend-node": "^1.0.1", + "@backstage/plugin-search-backend-module-elasticsearch": "^1.0.1", + "@backstage/plugin-search-backend-module-pg": "^0.3.6", + "@backstage/plugin-techdocs-backend": "^1.2.1", + "@backstage/plugin-tech-insights-backend": "^0.5.1", + "@backstage/plugin-tech-insights-node": "^0.3.3", + "@backstage/plugin-tech-insights-backend-module-jsonfc": "^0.1.19", + "@backstage/plugin-todo-backend": "^0.1.32", "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^19.0.3", "better-sqlite3": "^7.5.0", @@ -75,11 +76,11 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/dockerode": "^3.3.0", "@types/express": "^4.17.6", "@types/express-serve-static-core": "^4.17.5", - "@types/luxon": "^2.0.4" + "@types/luxon": "^3.0.0" }, "files": [ "dist" diff --git a/packages/backend/src/plugins/azure-devops.ts b/packages/backend/src/plugins/azure-devops.ts index 67bba8ac85..ed5b1d0068 100644 --- a/packages/backend/src/plugins/azure-devops.ts +++ b/packages/backend/src/plugins/azure-devops.ts @@ -24,5 +24,6 @@ export default async function createPlugin( return createRouter({ logger: env.logger, config: env.config, + reader: env.reader, }); } diff --git a/packages/backend/src/plugins/search.ts b/packages/backend/src/plugins/search.ts index c478ecdd05..084b1a54e5 100644 --- a/packages/backend/src/plugins/search.ts +++ b/packages/backend/src/plugins/search.ts @@ -22,8 +22,8 @@ import { PgSearchEngine } from '@backstage/plugin-search-backend-module-pg'; import { IndexBuilder, LunrSearchEngine, - SearchEngine, } from '@backstage/plugin-search-backend-node'; +import { SearchEngine } from '@backstage/plugin-search-common'; import { DefaultTechDocsCollatorFactory } from '@backstage/plugin-techdocs-backend'; import { Router } from 'express'; import { PluginEnvironment } from '../types'; diff --git a/packages/catalog-client/CHANGELOG.md b/packages/catalog-client/CHANGELOG.md index f2fc1d2c88..32ad01d0bf 100644 --- a/packages/catalog-client/CHANGELOG.md +++ b/packages/catalog-client/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/catalog-client +## 1.0.4 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.0 + - @backstage/errors@1.1.0 + ## 1.0.4-next.2 ### Patch Changes diff --git a/packages/catalog-client/api-report.md b/packages/catalog-client/api-report.md index 5fcae87dd5..964a3c1018 100644 --- a/packages/catalog-client/api-report.md +++ b/packages/catalog-client/api-report.md @@ -78,7 +78,7 @@ export class CatalogClient implements CatalogApi { }; }); addLocation( - { type, target, dryRun }: AddLocationRequest, + request: AddLocationRequest, options?: CatalogRequestOptions, ): Promise; getEntities( diff --git a/packages/catalog-client/package.json b/packages/catalog-client/package.json index a4678fb94b..e8e98d9fd0 100644 --- a/packages/catalog-client/package.json +++ b/packages/catalog-client/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/catalog-client", "description": "An isomorphic client for the catalog backend", - "version": "1.0.4-next.2", + "version": "1.0.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,14 +33,14 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/errors": "^1.1.0-next.0", + "@backstage/catalog-model": "^1.1.0", + "@backstage/errors": "^1.1.0", "cross-fetch": "^3.1.5" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1-next.0", "@types/jest": "^26.0.7", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/packages/catalog-client/src/CatalogClient.ts b/packages/catalog-client/src/CatalogClient.ts index 371ac55db4..8ddc3eb36d 100644 --- a/packages/catalog-client/src/CatalogClient.ts +++ b/packages/catalog-client/src/CatalogClient.ts @@ -272,9 +272,11 @@ export class CatalogClient implements CatalogApi { * {@inheritdoc CatalogApi.addLocation} */ async addLocation( - { type = 'url', target, dryRun }: AddLocationRequest, + request: AddLocationRequest, options?: CatalogRequestOptions, ): Promise { + const { type = 'url', target, dryRun } = request; + const response = await this.fetchApi.fetch( `${await this.discoveryApi.getBaseUrl('catalog')}/locations${ dryRun ? '?dryRun=true' : '' diff --git a/packages/catalog-model/CHANGELOG.md b/packages/catalog-model/CHANGELOG.md index d9eb2a04a5..9554b94788 100644 --- a/packages/catalog-model/CHANGELOG.md +++ b/packages/catalog-model/CHANGELOG.md @@ -1,5 +1,21 @@ # @backstage/catalog-model +## 1.1.0 + +### Minor Changes + +- 4cc81372f8: Introduced `GroupDefaultParentEntityPolicy` to set a default group entity parent. +- 1380b389dc: Adding an optional type field to entity links to group and categorize links + +### Patch Changes + +- c3cfc83af2: Updated JSDoc to be MDX compatible. +- f9f1de8100: Add shared annotations for Kubernetes clusters +- f1dcc6f3c6: Added type predicates for all entity types, e.g. isUserEntity +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- Updated dependencies + - @backstage/errors@1.1.0 + ## 1.1.0-next.3 ### Patch Changes diff --git a/packages/catalog-model/package.json b/packages/catalog-model/package.json index 081ffff289..40eb5419b3 100644 --- a/packages/catalog-model/package.json +++ b/packages/catalog-model/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/catalog-model", "description": "Types and validators that help describe the model of a Backstage Catalog", - "version": "1.1.0-next.3", + "version": "1.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,7 +35,7 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", + "@backstage/errors": "^1.1.0", "@backstage/types": "^1.0.0", "ajv": "^8.10.0", "json-schema": "^0.4.0", @@ -43,7 +43,7 @@ "uuid": "^8.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1-next.0", "@types/jest": "^26.0.7", "@types/json-schema": "^7.0.5", "@types/lodash": "^4.14.151", diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md index ba8f773fdb..4fdab1c48d 100644 --- a/packages/cli/CHANGELOG.md +++ b/packages/cli/CHANGELOG.md @@ -1,5 +1,67 @@ # @backstage/cli +## 0.18.1 + +### Patch Changes + +- d45bbfeb69: Linting is now ignored for any `.eslintrc.*` files, not just `.eslintrc.js`. +- 72c228fdb8: Fixed a bug where `NODE_ENV` was not set in the environment when starting the backend in development mode. It has always been the case that Webpack transformed `NODE_ENV` when running in development mode, but this did not affect dependencies in `node_modules` as they are treated as external. +- a539564c0d: Added Backstage version to output of `yarn backstage-cli info` command +- fd68d6f138: Added resolution of `.json` and `.wasm` files to the Webpack configuration in order to match defaults. +- 94155a41e0: Updated dependencies `@svgr/*` to `6.3.x`. + +## 0.18.1-next.1 + +### Patch Changes + +- fd68d6f138: Added resolution of `.json` and `.wasm` files to the Webpack configuration in order to match defaults. + +## 0.18.1-next.0 + +### Patch Changes + +- a539564c0d: Added Backstage version to output of `yarn backstage-cli info` command +- 94155a41e0: Updated dependencies `@svgr/*` to `6.3.x`. + +## 0.18.0 + +### Minor Changes + +- 96a82d9791: **BREAKING**: Removed the following deprecated package commands: + + - `app:build` - Use `package build` instead + - `app:serve` - Use `package start` instead + - `backend:build` - Use `package build` instead + - `backend:bundle` - Use `package build` instead + - `backend:dev` - Use `package start` instead + - `plugin:build` - Use `package build` instead + - `plugin:serve` - Use `package start` instead + - `build` - Use `package build` instead + - `lint` - Use `package lint` instead + - `prepack` - Use `package prepack` instead + - `postpack` - Use `package postpack` instead + + In order to replace these you need to have [migrated to using package roles](https://backstage.io/docs/tutorials/package-role-migration). + +### Patch Changes + +- 86640214f0: Upgrade `@rollup/plugin-node-resolve` to `^13.0.6` +- d2256c0384: Fix `webpack-dev-server` deprecations. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- e661242844: Updated dependency `run-script-webpack-plugin` to `^0.1.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- e8ed804d4f: Updated dependency `@spotify/prettier-config` to `^14.0.0`. + Updated dependency `@spotify/eslint-config-base` to `^14.0.0`. + Updated dependency `@spotify/eslint-config-react` to `^14.0.0`. + Updated dependency `@spotify/eslint-config-typescript` to `^14.0.0`. +- e662b573cf: Updated dependency `@octokit/request` to `^6.0.0`. +- f6b6fb7165: The `test` command now ensures that all IO is flushed before exiting when printing `--help`. +- Updated dependencies + - @backstage/config-loader@1.1.3 + - @backstage/release-manifests@0.0.5 + - @backstage/errors@1.1.0 + ## 0.18.0-next.3 ### Patch Changes diff --git a/packages/cli/config/eslint-factory.js b/packages/cli/config/eslint-factory.js index e86146048e..6e2a510c4a 100644 --- a/packages/cli/config/eslint-factory.js +++ b/packages/cli/config/eslint-factory.js @@ -76,7 +76,7 @@ function createConfig(dir, extraConfig = {}) { ...parserOptions, }, ignorePatterns: [ - '.eslintrc.js', + '.eslintrc.*', '**/dist/**', '**/dist-types/**', ...(ignorePatterns ?? []), diff --git a/packages/cli/package.json b/packages/cli/package.json index ab0c8ac4d3..34987bd19b 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/cli", "description": "CLI for developing Backstage plugins and apps", - "version": "0.18.0-next.3", + "version": "0.18.1", "private": false, "publishConfig": { "access": "public" @@ -33,9 +33,9 @@ "dependencies": { "@backstage/cli-common": "^0.1.9", "@backstage/config": "^1.0.1", - "@backstage/config-loader": "^1.1.3-next.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/release-manifests": "^0.0.5-next.0", + "@backstage/config-loader": "^1.1.3", + "@backstage/errors": "^1.1.0", + "@backstage/release-manifests": "^0.0.5", "@backstage/types": "^1.0.0", "@hot-loader/react-dom-v16": "npm:@hot-loader/react-dom@^16.0.2", "@hot-loader/react-dom-v17": "npm:@hot-loader/react-dom@^17.0.2", @@ -50,10 +50,10 @@ "@spotify/eslint-config-typescript": "^14.0.0", "@sucrase/jest-plugin": "^2.1.1", "@sucrase/webpack-loader": "^2.0.0", - "@svgr/plugin-jsx": "6.2.x", - "@svgr/plugin-svgo": "6.2.x", - "@svgr/rollup": "6.2.x", - "@svgr/webpack": "6.2.x", + "@svgr/plugin-jsx": "6.3.x", + "@svgr/plugin-svgo": "6.3.x", + "@svgr/rollup": "6.3.x", + "@svgr/webpack": "6.3.x", "@types/webpack-env": "^1.15.2", "@typescript-eslint/eslint-plugin": "^5.9.0", "@typescript-eslint/parser": "^5.9.0", @@ -126,14 +126,14 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/backend-common": "^0.14.1-next.3", + "@backstage/backend-common": "^0.15.0", "@backstage/config": "^1.0.1", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", + "@backstage/theme": "^0.2.16", "@types/diff": "^5.0.0", "@types/express": "^4.17.6", "@types/fs-extra": "^9.0.1", @@ -152,7 +152,7 @@ "@types/yarnpkg__lockfile": "^1.1.4", "del": "^6.0.0", "mock-fs": "^5.1.0", - "msw": "^0.44.0", + "msw": "^0.45.0", "nodemon": "^2.0.2", "ts-node": "^10.0.0" }, diff --git a/packages/cli/src/commands/info.ts b/packages/cli/src/commands/info.ts index 4042d2cb8e..f3740de1a9 100644 --- a/packages/cli/src/commands/info.ts +++ b/packages/cli/src/commands/info.ts @@ -19,17 +19,30 @@ import os from 'os'; import { runPlain } from '../lib/run'; import { paths } from '../lib/paths'; import { Lockfile } from '../lib/versioning'; +import fs from 'fs-extra'; export default async () => { await new Promise(async () => { const yarnVersion = await runPlain('yarn --version'); - // eslint-disable-next-line no-restricted-syntax - const isLocal = require('fs').existsSync(paths.resolveOwn('./src')); + const isLocal = fs.existsSync(paths.resolveOwn('./src')); + + const backstageFile = paths.resolveTargetRoot('backstage.json'); + let backstageVersion = 'N/A'; + if (fs.existsSync(backstageFile)) { + try { + const backstageJson = await fs.readJSON(backstageFile); + backstageVersion = backstageJson.version ?? 'N/A'; + } catch (error) { + console.warn('The "backstage.json" file is not in the expected format'); + console.log(); + } + } console.log(`OS: ${os.type} ${os.release} - ${os.platform}/${os.arch}`); console.log(`node: ${process.version}`); console.log(`yarn: ${yarnVersion}`); console.log(`cli: ${cliVersion} (${isLocal ? 'local' : 'installed'})`); + console.log(`backstage: ${backstageVersion}`); console.log(); console.log('Dependencies:'); const lockfilePath = paths.resolveTargetRoot('yarn.lock'); diff --git a/packages/cli/src/lib/bundler/backend.ts b/packages/cli/src/lib/bundler/backend.ts index 1b161976e3..3094450d4b 100644 --- a/packages/cli/src/lib/bundler/backend.ts +++ b/packages/cli/src/lib/bundler/backend.ts @@ -26,6 +26,10 @@ export async function serveBackend(options: BackendServeOptions) { isDev: true, }); + // Webpack only replaces occurrences of this in code it touches, which does + // not include dependencies in node_modules. So we set it here at runtime as well. + (process.env as { NODE_ENV: string }).NODE_ENV = 'development'; + const compiler = webpack(config, (err: Error | undefined) => { if (err) { console.error(err); diff --git a/packages/cli/src/lib/bundler/config.ts b/packages/cli/src/lib/bundler/config.ts index d723b963bd..057474ea9a 100644 --- a/packages/cli/src/lib/bundler/config.ts +++ b/packages/cli/src/lib/bundler/config.ts @@ -162,7 +162,7 @@ export async function createConfig( context: paths.targetPath, entry: [require.resolve('react-hot-loader/patch'), paths.targetEntry], resolve: { - extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'], + extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx', '.json', '.wasm'], mainFields: ['browser', 'module', 'main'], fallback: { ...pickBy(require('node-libs-browser')), @@ -272,7 +272,7 @@ export async function createBackendConfig( paths.targetRunFile ? paths.targetRunFile : paths.targetEntry, ], resolve: { - extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx'], + extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx', '.json'], mainFields: ['main'], modules: [paths.rootNodeModules, ...moduleDirs], plugins: [ diff --git a/packages/cli/templates/default-backend-plugin/package.json.hbs b/packages/cli/templates/default-backend-plugin/package.json.hbs index 0a5600ad24..3b9a34db33 100644 --- a/packages/cli/templates/default-backend-plugin/package.json.hbs +++ b/packages/cli/templates/default-backend-plugin/package.json.hbs @@ -41,7 +41,7 @@ "@backstage/cli": "{{versionQuery '@backstage/cli'}}", "@types/supertest": "{{versionQuery '@types/supertest' '2.0.8'}}", "supertest": "{{versionQuery 'supertest' '4.0.2'}}", - "msw": "{{versionQuery 'msw' '0.44.0'}}" + "msw": "{{versionQuery 'msw' '0.45.0'}}" }, "files": [ "dist" diff --git a/packages/cli/templates/default-plugin/package.json.hbs b/packages/cli/templates/default-plugin/package.json.hbs index f084d59a8e..540bd75755 100644 --- a/packages/cli/templates/default-plugin/package.json.hbs +++ b/packages/cli/templates/default-plugin/package.json.hbs @@ -49,7 +49,7 @@ "@testing-library/user-event": "{{versionQuery '@testing-library/user-event' '14.0.0'}}", "@types/jest": "{{versionQuery '@types/jest' '26.0.7'}}", "@types/node": "{{versionQuery '@types/node' '16.11.26'}}", - "msw": "{{versionQuery 'msw' '0.44.0'}}", + "msw": "{{versionQuery 'msw' '0.45.0'}}", "cross-fetch": "{{versionQuery 'cross-fetch' '3.1.5'}}" }, "files": [ diff --git a/packages/config-loader/CHANGELOG.md b/packages/config-loader/CHANGELOG.md index f5b5846a42..484795ce5b 100644 --- a/packages/config-loader/CHANGELOG.md +++ b/packages/config-loader/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/config-loader +## 1.1.3 + +### Patch Changes + +- bcada7cd9f: From now on the `$file` placeholder will trim the whitespaces and newline characters from the end of the file it reads. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- a3acec8819: Updated dependency `typescript-json-schema` to `^0.54.0`. +- Updated dependencies + - @backstage/errors@1.1.0 + ## 1.1.3-next.1 ### Patch Changes diff --git a/packages/config-loader/package.json b/packages/config-loader/package.json index c87d28b690..671e304199 100644 --- a/packages/config-loader/package.json +++ b/packages/config-loader/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/config-loader", "description": "Config loading functionality used by Backstage backend, and CLI", - "version": "1.1.3-next.1", + "version": "1.1.3", "private": false, "publishConfig": { "access": "public", @@ -36,7 +36,7 @@ "dependencies": { "@backstage/cli-common": "^0.1.9", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", + "@backstage/errors": "^1.1.0", "@backstage/types": "^1.0.0", "@types/json-schema": "^7.0.6", "ajv": "^8.10.0", @@ -57,7 +57,7 @@ "@types/node": "^16.11.26", "@types/yup": "^0.29.13", "mock-fs": "^5.1.0", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/packages/config-loader/src/lib/transform/include.test.ts b/packages/config-loader/src/lib/transform/include.test.ts index 0913b31f66..c80efe6785 100644 --- a/packages/config-loader/src/lib/transform/include.test.ts +++ b/packages/config-loader/src/lib/transform/include.test.ts @@ -49,6 +49,8 @@ const readFile = jest.fn(async (path: string) => { const content = ( { [resolvePath(root, 'my-secret')]: 'secret', + [resolvePath(root, 'with-newline-at-the-end')]: + 'value without newline at the end\n\n', [resolvePath(root, 'my-data.json')]: '{"a":{"b":{"c":42}}}', [resolvePath(root, 'my-data.yaml')]: 'some:\n yaml:\n key: 7', [resolvePath(root, 'my-data.yml')]: 'different: { key: hello }', @@ -92,6 +94,14 @@ describe('includeTransform', () => { includeTransform({ $file: 'no-secret' }, root), ).rejects.toThrow('File not found!'); }); + it('should trim newlines from end of file', async () => { + await expect( + includeTransform({ $file: 'with-newline-at-the-end' }, root), + ).resolves.toEqual({ + applied: true, + value: 'value without newline at the end', + }); + }); it('should include env vars', async () => { await expect(includeTransform({ $env: 'SECRET' }, root)).resolves.toEqual({ diff --git a/packages/config-loader/src/lib/transform/include.ts b/packages/config-loader/src/lib/transform/include.ts index 569b61c82c..84e4a9294d 100644 --- a/packages/config-loader/src/lib/transform/include.ts +++ b/packages/config-loader/src/lib/transform/include.ts @@ -73,7 +73,7 @@ export function createIncludeTransform( case '$file': try { const value = await readFile(resolvePath(baseDir, includeValue)); - return { applied: true, value }; + return { applied: true, value: value.trimEnd() }; } catch (error) { throw new Error(`failed to read file ${includeValue}, ${error}`); } diff --git a/packages/config/package.json b/packages/config/package.json index fc99531bb4..eebebf0b59 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -37,7 +37,7 @@ "lodash": "^4.17.21" }, "devDependencies": { - "@backstage/test-utils": "^1.1.2-next.0", + "@backstage/test-utils": "^1.1.3-next.0", "@types/jest": "^26.0.7", "@types/node": "^16.0.0" }, diff --git a/packages/core-app-api/CHANGELOG.md b/packages/core-app-api/CHANGELOG.md index 115b41d76e..8a14eed4ec 100644 --- a/packages/core-app-api/CHANGELOG.md +++ b/packages/core-app-api/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/core-app-api +## 1.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + +## 1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + +## 1.0.4 + +### Patch Changes + +- 881fc75a75: Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. +- 8fe2357101: The `signOut` method of the `IdentityApi` will now navigate the user back to the base URL of the app as indicated by the `app.baseUrl` config. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.4 + ## 1.0.4-next.1 ### Patch Changes diff --git a/packages/core-app-api/api-report.md b/packages/core-app-api/api-report.md index beb0d11201..3cc1f4a8a8 100644 --- a/packages/core-app-api/api-report.md +++ b/packages/core-app-api/api-report.md @@ -157,6 +157,7 @@ export type AppConfigLoader = () => Promise; export type AppContext = { getPlugins(): BackstagePlugin[]; getSystemIcon(key: string): IconComponent | undefined; + getSystemIcons(): Record; getComponents(): AppComponents; }; diff --git a/packages/core-app-api/package.json b/packages/core-app-api/package.json index 34c44fe6e0..1fccec666d 100644 --- a/packages/core-app-api/package.json +++ b/packages/core-app-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-app-api", "description": "Core app API used by Backstage apps", - "version": "1.0.4-next.1", + "version": "1.0.5", "private": false, "publishConfig": { "access": "public", @@ -34,7 +34,7 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/core-plugin-api": "^1.0.4-next.0", + "@backstage/core-plugin-api": "^1.0.5", "@backstage/types": "^1.0.0", "@backstage/version-bridge": "^1.0.1", "@types/prop-types": "^15.7.3", @@ -49,8 +49,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", @@ -59,7 +59,7 @@ "@types/node": "^16.11.26", "@types/zen-observable": "^0.8.0", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts index 3d4f83b05d..6fa46db7c9 100644 --- a/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts +++ b/packages/core-app-api/src/apis/implementations/IdentityApi/AppIdentityProxy.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { withLogCollector } from '@backstage//test-utils'; +import { withLogCollector } from '@backstage/test-utils'; import { AppIdentityProxy } from './AppIdentityProxy'; describe('AppIdentityProxy', () => { diff --git a/packages/core-app-api/src/app/AppContext.test.tsx b/packages/core-app-api/src/app/AppContext.test.tsx index bc67ee3a9e..a27b7c6f35 100644 --- a/packages/core-app-api/src/app/AppContext.test.tsx +++ b/packages/core-app-api/src/app/AppContext.test.tsx @@ -36,6 +36,7 @@ describe('v1 consumer', () => { getPlugins: jest.fn(), getComponents: jest.fn(), getSystemIcon: jest.fn(), + getSystemIcons: jest.fn(), }; const renderedHook = renderHook(() => useMockAppV1(), { diff --git a/packages/core-app-api/src/app/AppManager.tsx b/packages/core-app-api/src/app/AppManager.tsx index 72c69f7da4..f36d37f796 100644 --- a/packages/core-app-api/src/app/AppManager.tsx +++ b/packages/core-app-api/src/app/AppManager.tsx @@ -153,6 +153,10 @@ class AppContextImpl implements AppContext { return this.app.getSystemIcon(key); } + getSystemIcons(): Record { + return this.app.getSystemIcons(); + } + getComponents(): AppComponents { return this.app.getComponents(); } @@ -194,6 +198,10 @@ export class AppManager implements BackstageApp { return this.icons[key]; } + getSystemIcons(): Record { + return this.icons; + } + getComponents(): AppComponents { return this.components; } diff --git a/packages/core-app-api/src/app/types.ts b/packages/core-app-api/src/app/types.ts index 979fb0496e..39bf9c0554 100644 --- a/packages/core-app-api/src/app/types.ts +++ b/packages/core-app-api/src/app/types.ts @@ -328,6 +328,11 @@ export type AppContext = { */ getSystemIcon(key: string): IconComponent | undefined; + /** + * Get a list of common and custom icons for this app. + */ + getSystemIcons(): Record; + /** * Get the components registered for various purposes in the app. */ diff --git a/packages/core-app-api/src/routing/RoutingProvider.test.tsx b/packages/core-app-api/src/routing/RoutingProvider.test.tsx index dec92072fc..c559c0fff0 100644 --- a/packages/core-app-api/src/routing/RoutingProvider.test.tsx +++ b/packages/core-app-api/src/routing/RoutingProvider.test.tsx @@ -124,6 +124,7 @@ const Extension5 = plugin.provide( const mockContext = { getComponents: () => ({ Progress: () => null } as any), getSystemIcon: jest.fn(), + getSystemIcons: jest.fn(), getPlugins: jest.fn(), }; diff --git a/packages/core-components/CHANGELOG.md b/packages/core-components/CHANGELOG.md index 8952d3be8f..c1cd9e33ac 100644 --- a/packages/core-components/CHANGELOG.md +++ b/packages/core-components/CHANGELOG.md @@ -1,5 +1,61 @@ # @backstage/core-components +## 0.11.0 + +### Minor Changes + +- d0eefc499a: Made the `to` prop of `Button` and `Link` more strict, only supporting plain strings. It used to be the case that this prop was unexpectedly too liberal, making it look like we supported the complex `react-router-dom` object form of the parameter as well, which led to unexpected results at runtime. + +### Patch Changes + +- a22af3edc8: Adding a `className` prop to the `MarkdownContent` component +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + +## 0.11.0-next.2 + +### Minor Changes + +- d0eefc499a: Made the `to` prop of `Button` and `Link` more strict, only supporting plain strings. It used to be the case that this prop was unexpectedly too liberal, making it look like we supported the complex `react-router-dom` object form of the parameter as well, which led to unexpected results at runtime. + +## 0.10.1-next.1 + +### Patch Changes + +- a22af3edc8: Adding a `className` prop to the `MarkdownContent` component + +## 0.10.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + +## 0.10.0 + +### Minor Changes + +- 32204fa794: Add `transformLinkUri` and `transformImageUri` to `MarkdownContent` + +### Patch Changes + +- 3c440ea77e: Change BackstageIconLinkVertical style to use pallette instead of explicit color +- c3cfc83af2: Updated JSDoc to be MDX compatible. +- b4b711bcc2: Fix the EntityLayout header style so that EntityContextMenu button can display in correct shape when user hover on it +- 944af7f2a8: Work around a bug calling `onChange` twice in `mui` for `RoutedTab` so you don't have to press back twice to navigate through tabs +- 7f5e79961d: Fix relative `sub-paths` by concatenating the app's base path with them. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 693990d4fe: Updated dependency `@react-hookz/web` to `^15.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 15201b1032: Updated dependency `rc-progress` to `3.4.0`. +- 7e115d42f9: Support displaying subtitle text in `SidebarSubmenuItem` +- ae746946f7: Improve accessibility for CopyTextButton +- 385389d23c: Updated to remove usage of the `bursts` object in the theme palette +- Updated dependencies + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.10.0-next.3 ### Patch Changes diff --git a/packages/core-components/api-report.md b/packages/core-components/api-report.md index 4e3820967a..3dc4e2848e 100644 --- a/packages/core-components/api-report.md +++ b/packages/core-components/api-report.md @@ -613,8 +613,9 @@ export const Link: (props: LinkProps) => JSX.Element; // Warning: (ae-missing-release-tag) "LinkProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export type LinkProps = LinkProps_2 & - LinkProps_3 & { +export type LinkProps = Omit & + Omit & { + to: string; component?: ElementType; noTrack?: boolean; }; @@ -986,13 +987,10 @@ export type SidebarOpenState = { }; // @public -export const SidebarOpenStateProvider: ({ - children, - value, -}: { +export function SidebarOpenStateProvider(props: { children: ReactNode; value: SidebarOpenState; -}) => JSX.Element; +}): JSX.Element; // @public (undocumented) export type SidebarOptions = { @@ -1033,13 +1031,10 @@ export type SidebarPinStateContextType = { }; // @public -export const SidebarPinStateProvider: ({ - children, - value, -}: { +export function SidebarPinStateProvider(props: { children: ReactNode; value: SidebarPinStateContextType; -}) => JSX.Element; +}): JSX.Element; // @public (undocumented) export type SidebarProps = { diff --git a/packages/core-components/package.json b/packages/core-components/package.json index 43ab5d1775..7b59f8cfd6 100644 --- a/packages/core-components/package.json +++ b/packages/core-components/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-components", "description": "Core components used by Backstage plugins and apps", - "version": "0.10.0-next.3", + "version": "0.11.0", "private": false, "publishConfig": { "access": "public", @@ -34,9 +34,9 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/theme": "^0.2.16", "@backstage/version-bridge": "^1.0.1", "@material-table/core": "^3.1.0", "@material-ui/core": "^4.12.2", @@ -79,9 +79,9 @@ "react-dom": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/cli": "^0.18.0-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/core-app-api": "^1.0.5", + "@backstage/cli": "^0.18.1", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", @@ -101,7 +101,7 @@ "@types/react-window": "^1.8.5", "@types/zen-observable": "^0.8.0", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/packages/core-components/src/components/Link/Link.tsx b/packages/core-components/src/components/Link/Link.tsx index 22b203d157..92ac92daad 100644 --- a/packages/core-components/src/components/Link/Link.tsx +++ b/packages/core-components/src/components/Link/Link.tsx @@ -47,8 +47,9 @@ const useStyles = makeStyles( export const isExternalUri = (uri: string) => /^([a-z+.-]+):/.test(uri); -export type LinkProps = MaterialLinkProps & - RouterLinkProps & { +export type LinkProps = Omit & + Omit & { + to: string; component?: ElementType; noTrack?: boolean; }; diff --git a/packages/core-components/src/components/MarkdownContent/MarkdownContent.test.tsx b/packages/core-components/src/components/MarkdownContent/MarkdownContent.test.tsx index 9c08b83c40..fa8cb35ca8 100644 --- a/packages/core-components/src/components/MarkdownContent/MarkdownContent.test.tsx +++ b/packages/core-components/src/components/MarkdownContent/MarkdownContent.test.tsx @@ -100,4 +100,34 @@ describe('', () => { 'https://example.com/blog/assets/6/header.png', ); }); + + it('render MarkdownContent component with headings given proper ids', async () => { + const rendered = await renderWithEffects( + wrapInTestApp( + , + ), + ); + + expect(rendered.getByText('Lorem ipsum').getAttribute('id')).toEqual( + 'lorem-ipsum', + ); + expect(rendered.getByText('bing bong').getAttribute('id')).toEqual( + 'bing-bong', + ); + expect( + rendered + .getByText( + 'The FitnessGram Pacer Test is a multistage aerobic capacity test', + ) + .getAttribute('id'), + ).toEqual( + 'the-fitnessgram-pacer-test-is-a-multistage-aerobic-capacity-test', + ); + }); }); diff --git a/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx b/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx index 0e5aedda90..d97172bf75 100644 --- a/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx +++ b/packages/core-components/src/components/MarkdownContent/MarkdownContent.tsx @@ -20,6 +20,7 @@ import gfm from 'remark-gfm'; import React from 'react'; import { BackstageTheme } from '@backstage/theme'; import { CodeSnippet } from '../CodeSnippet'; +import { HeadingProps } from 'react-markdown/lib/ast-to-react'; export type MarkdownContentClassKey = 'markdown'; @@ -70,6 +71,22 @@ type Props = { linkTarget?: Options['linkTarget']; transformLinkUri?: (href: string) => string; transformImageUri?: (href: string) => string; + className?: string; +}; + +const flatten = (text: string, child: any): string => { + if (!child) return text; + + return typeof child === 'string' + ? text + child + : React.Children.toArray(child.props.children).reduce(flatten, text); +}; + +const headingRenderer = ({ level, children }: HeadingProps) => { + const childrenArray = React.Children.toArray(children); + const text = childrenArray.reduce(flatten, ''); + const slug = text.toLocaleLowerCase('en-US').replace(/\W/g, '-'); + return React.createElement(`h${level}`, { id: slug }, children); }; const components: Options['components'] = { @@ -84,6 +101,12 @@ const components: Options['components'] = { ); }, + h1: headingRenderer, + h2: headingRenderer, + h3: headingRenderer, + h4: headingRenderer, + h5: headingRenderer, + h6: headingRenderer, }; /** @@ -99,12 +122,13 @@ export function MarkdownContent(props: Props) { linkTarget, transformLinkUri, transformImageUri, + className, } = props; const classes = useStyles(); return ( ( @@ -206,6 +208,7 @@ export function SelectComponent(props: SelectProps) { data-testid="select" displayEmpty multiple={multiple} + margin={margin} onChange={handleChange} onClick={handleClick} open={isOpen} diff --git a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx index 0a937683a5..a97fc70e4b 100644 --- a/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx +++ b/packages/core-components/src/layout/HeaderTabs/HeaderTabs.tsx @@ -20,7 +20,7 @@ import { makeStyles } from '@material-ui/core/styles'; import TabUI, { TabProps } from '@material-ui/core/Tab'; import Tabs from '@material-ui/core/Tabs'; -import React, { useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState } from 'react'; /** @public */ export type HeaderTabsClassKey = @@ -80,12 +80,15 @@ export function HeaderTabs(props: HeaderTabsProps) { const [selectedTab, setSelectedTab] = useState(selectedIndex ?? 0); const styles = useStyles(); - const handleChange = (_: React.ChangeEvent<{}>, index: number) => { - if (selectedIndex === undefined) { - setSelectedTab(index); - } - if (onChange) onChange(index); - }; + const handleChange = useCallback( + (_: React.ChangeEvent<{}>, index: number) => { + if (selectedIndex === undefined) { + setSelectedTab(index); + } + if (onChange && selectedIndex !== index) onChange(index); + }, + [selectedIndex, onChange], + ); useEffect(() => { if (selectedIndex !== undefined) { diff --git a/packages/core-components/src/layout/Sidebar/SidebarOpenStateContext.tsx b/packages/core-components/src/layout/Sidebar/SidebarOpenStateContext.tsx index 7cb0e5b2c3..36e87b07a2 100644 --- a/packages/core-components/src/layout/Sidebar/SidebarOpenStateContext.tsx +++ b/packages/core-components/src/layout/Sidebar/SidebarOpenStateContext.tsx @@ -74,21 +74,21 @@ const VersionedSidebarContext = createVersionedContext<{ * * @public */ -export const SidebarOpenStateProvider = ({ - children, - value, -}: { +export function SidebarOpenStateProvider(props: { children: ReactNode; value: SidebarOpenState; -}) => ( - - - {children} - - -); +}) { + const { children, value } = props; + return ( + + + {children} + + + ); +} /** * Hook to read and update the sidebar's open state, which controls whether or diff --git a/packages/core-components/src/layout/Sidebar/SidebarPinStateContext.tsx b/packages/core-components/src/layout/Sidebar/SidebarPinStateContext.tsx index e00ed259e9..9c58a32732 100644 --- a/packages/core-components/src/layout/Sidebar/SidebarPinStateContext.tsx +++ b/packages/core-components/src/layout/Sidebar/SidebarPinStateContext.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { createVersionedContext, createVersionedValueMap, @@ -22,8 +23,8 @@ import React, { createContext, ReactNode, useContext } from 'react'; /** * Type of `SidebarPinStateContext` * - * @public @deprecated - * Use `SidebarPinState` instead. + * @public + * @deprecated Use `SidebarPinState` instead. */ export type SidebarPinStateContextType = { isPinned: boolean; @@ -80,21 +81,21 @@ const VersionedSidebarPinStateContext = createVersionedContext<{ * * @public */ -export const SidebarPinStateProvider = ({ - children, - value, -}: { +export function SidebarPinStateProvider(props: { children: ReactNode; value: SidebarPinStateContextType; -}) => ( - - - {children} - - -); +}) { + const { children, value } = props; + return ( + + + {children} + + + ); +} /** * Hook to read and update sidebar pin state, which controls whether or not the diff --git a/packages/core-plugin-api/CHANGELOG.md b/packages/core-plugin-api/CHANGELOG.md index 0d3cf6dabe..807718212c 100644 --- a/packages/core-plugin-api/CHANGELOG.md +++ b/packages/core-plugin-api/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/core-plugin-api +## 1.0.5 + +### Patch Changes + +- 80da5162c7: Introduced a new experimental feature that allows you to declare plugin-wide options for your plugin by defining + `__experimentalConfigure` in your `createPlugin` options. See https://backstage.io/docs/plugins/customization.md for more information. + + This is an experimental feature and it will have breaking changes in the future. + +- 87649a06bf: Add a note that the `fetchApi` utility should not be used on sign-in page implementations and similar. + +## 1.0.5-next.0 + +### Patch Changes + +- 80da5162c7: Introduced a new experimental feature that allows you to declare plugin-wide options for your plugin by defining + `__experimentalConfigure` in your `createPlugin` options. See https://backstage.io/docs/plugins/customization.md for more information. + + This is an experimental feature and it will have breaking changes in the future. + +## 1.0.4 + +### Patch Changes + +- 881fc75a75: Internal tweak removing usage of explicit type parameters for the `BackstagePlugin` type. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 2990fff4e5: Enabled the `@backstage/core-plugin-api/alpha` entry point. + ## 1.0.4-next.0 ### Patch Changes diff --git a/packages/core-plugin-api/api-report.md b/packages/core-plugin-api/api-report.md index 1921c1b715..0738d7bac5 100644 --- a/packages/core-plugin-api/api-report.md +++ b/packages/core-plugin-api/api-report.md @@ -149,6 +149,7 @@ export type AppComponents = { export type AppContext = { getPlugins(): BackstagePlugin_2[]; getSystemIcon(key: string): IconComponent_2 | undefined; + getSystemIcons(): Record; getComponents(): AppComponents; }; @@ -214,6 +215,7 @@ export type BackstageIdentityResponse = { export type BackstagePlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, + PluginInputOptions extends {} = {}, > = { getId(): string; getApis(): Iterable; @@ -221,6 +223,7 @@ export type BackstagePlugin< provide(extension: Extension): T; routes: Routes; externalRoutes: ExternalRoutes; + __experimentalReconfigure(options: PluginInputOptions): void; }; // @public @@ -303,9 +306,10 @@ export function createExternalRouteRef< export function createPlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, + PluginInputOptions extends {} = {}, >( - config: PluginConfig, -): BackstagePlugin; + config: PluginConfig, +): BackstagePlugin; // @public export function createReactExtension< @@ -621,12 +625,14 @@ export type PendingOAuthRequest = { export type PluginConfig< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, + PluginInputOptions extends {}, > = { id: string; apis?: Iterable; routes?: Routes; externalRoutes?: ExternalRoutes; featureFlags?: PluginFeatureFlagConfig[]; + __experimentalConfigure?(options?: PluginInputOptions): {}; }; // @public @@ -634,6 +640,17 @@ export type PluginFeatureFlagConfig = { name: string; }; +// @alpha +export interface PluginOptionsProviderProps { + // (undocumented) + children: ReactNode; + // (undocumented) + plugin?: BackstagePlugin; +} + +// @alpha +export const PluginProvider: (props: PluginOptionsProviderProps) => JSX.Element; + // @public export type ProfileInfo = { email?: string; @@ -734,6 +751,11 @@ export function useElementFilter( dependencies?: any[], ): T; +// @alpha +export function usePluginOptions< + TPluginOptions extends {} = {}, +>(): TPluginOptions; + // @public export function useRouteRef( routeRef: ExternalRouteRef, diff --git a/packages/core-plugin-api/package.json b/packages/core-plugin-api/package.json index 132abe72a5..573f74d864 100644 --- a/packages/core-plugin-api/package.json +++ b/packages/core-plugin-api/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/core-plugin-api", "description": "Core API used by Backstage plugins", - "version": "1.0.4-next.0", + "version": "1.0.5", "private": false, "publishConfig": { "access": "public", @@ -47,9 +47,9 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", @@ -59,7 +59,7 @@ "@types/prop-types": "^15.7.3", "@types/zen-observable": "^0.8.0", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/packages/core-plugin-api/src/apis/definitions/FetchApi.ts b/packages/core-plugin-api/src/apis/definitions/FetchApi.ts index b1a4dbbd0b..aba0e53bb7 100644 --- a/packages/core-plugin-api/src/apis/definitions/FetchApi.ts +++ b/packages/core-plugin-api/src/apis/definitions/FetchApi.ts @@ -37,6 +37,13 @@ export type FetchApi = { * This is a wrapper for the fetch API, that has additional behaviors such as * the ability to automatically inject auth information where necessary. * + * Note that the default behavior of this API (unless overridden by your org), + * is to require that the user is already signed in so that it has auth + * information to inject. Therefore, using the default implementation of this + * utility API e.g. on the `SignInPage` or similar, would cause issues. In + * special circumstances like those, you can use the regular system `fetch` + * instead. + * * @public */ export const fetchApiRef: ApiRef = createApiRef({ diff --git a/packages/core-plugin-api/src/extensions/extensions.tsx b/packages/core-plugin-api/src/extensions/extensions.tsx index efc8e3525d..18b815debf 100644 --- a/packages/core-plugin-api/src/extensions/extensions.tsx +++ b/packages/core-plugin-api/src/extensions/extensions.tsx @@ -15,12 +15,13 @@ */ import React, { lazy, Suspense } from 'react'; -import { AnalyticsContext } from '../analytics/AnalyticsContext'; +import { AnalyticsContext } from '../analytics'; import { useApp } from '../app'; import { RouteRef, useRouteRef } from '../routing'; import { attachComponentData } from './componentData'; -import { Extension, BackstagePlugin } from '../plugin/types'; +import { Extension, BackstagePlugin } from '../plugin'; import { PluginErrorBoundary } from './PluginErrorBoundary'; +import { PluginProvider } from '../plugin-options'; /** * Lazy or synchronous retrieving of extension components. @@ -245,7 +246,9 @@ export function createReactExtension< ...(mountPoint && { routeRef: mountPoint.id }), }} > - + + + diff --git a/packages/core-plugin-api/src/index.ts b/packages/core-plugin-api/src/index.ts index 30fc35b62a..e8edd38ff3 100644 --- a/packages/core-plugin-api/src/index.ts +++ b/packages/core-plugin-api/src/index.ts @@ -22,6 +22,7 @@ export * from './analytics'; export * from './apis'; +export * from './plugin-options'; export * from './app'; export * from './extensions'; export * from './icons'; diff --git a/packages/core-plugin-api/src/plugin-options/index.ts b/packages/core-plugin-api/src/plugin-options/index.ts new file mode 100644 index 0000000000..1737a1c836 --- /dev/null +++ b/packages/core-plugin-api/src/plugin-options/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { usePluginOptions, PluginProvider } from './usePluginOptions'; +export type { PluginOptionsProviderProps } from './usePluginOptions'; diff --git a/packages/core-plugin-api/src/plugin-options/usePluginOptions.test.tsx b/packages/core-plugin-api/src/plugin-options/usePluginOptions.test.tsx new file mode 100644 index 0000000000..11bf85aafa --- /dev/null +++ b/packages/core-plugin-api/src/plugin-options/usePluginOptions.test.tsx @@ -0,0 +1,53 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { renderHook } from '@testing-library/react-hooks'; +import { usePluginOptions, PluginProvider } from './usePluginOptions'; +import { createPlugin } from '../plugin'; + +describe('usePluginOptions', () => { + it('should provide a versioned value to hook', () => { + type TestInputPluginOptions = { + 'key-1': string; + }; + + type TestPluginOptions = { + 'key-1': string; + 'key-2': string; + }; + + const plugin = createPlugin({ + id: 'my-plugin', + __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { + return { 'key-1': 'value-1', 'key-2': 'value-2' }; + }, + }); + + const rendered = renderHook(() => usePluginOptions(), { + wrapper: ({ children }) => ( + {children} + ), + }); + + const config = rendered.result.current; + + expect(config).toEqual({ + 'key-1': 'value-1', + 'key-2': 'value-2', + }); + }); +}); diff --git a/packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx b/packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx new file mode 100644 index 0000000000..4fdacc1ace --- /dev/null +++ b/packages/core-plugin-api/src/plugin-options/usePluginOptions.tsx @@ -0,0 +1,93 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createVersionedContext, + createVersionedValueMap, + useVersionedContext, +} from '@backstage/version-bridge'; +import { BackstagePlugin } from '../plugin'; +import React, { ReactNode } from 'react'; + +const contextKey: string = 'plugin-context'; + +/** + * Properties for the PluginProvider component. + * + * @alpha + */ +export interface PluginOptionsProviderProps { + children: ReactNode; + plugin?: BackstagePlugin; +} + +/** + * Contains the plugin configuration. + * + * @alpha + */ +export const PluginProvider = ( + props: PluginOptionsProviderProps, +): JSX.Element => { + const { children, plugin } = props; + + const { Provider } = createVersionedContext<{ + 1: { plugin: BackstagePlugin | undefined }; + }>(contextKey); + + return ( + + {children} + + ); +}; + +/** + * Grab the current entity from the context, throws if the entity has not yet been loaded + * or is not available. + * + * @alpha + */ +export function usePluginOptions< + TPluginOptions extends {} = {}, +>(): TPluginOptions { + const versionedHolder = useVersionedContext<{ 1: TPluginOptions }>( + contextKey, + ); + + if (!versionedHolder) { + throw new Error('Plugin Options context is not available'); + } + + const value = versionedHolder.atVersion(1); + if (!value) { + throw new Error('Plugin Options v1 is not available'); + } + + return ( + value as unknown as { + plugin: { + getPluginOptions(): {}; + }; + } + ).plugin.getPluginOptions() as TPluginOptions; +} diff --git a/packages/core-plugin-api/src/plugin/Plugin.tsx b/packages/core-plugin-api/src/plugin/Plugin.tsx index d97554b27b..da26cd4db0 100644 --- a/packages/core-plugin-api/src/plugin/Plugin.tsx +++ b/packages/core-plugin-api/src/plugin/Plugin.tsx @@ -30,9 +30,18 @@ import { AnyApiFactory } from '../apis'; export class PluginImpl< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, -> implements BackstagePlugin + PluginInputOptions extends {}, +> implements BackstagePlugin { - constructor(private readonly config: PluginConfig) {} + constructor( + private readonly config: PluginConfig< + Routes, + ExternalRoutes, + PluginInputOptions + >, + ) {} + + private options: {} | undefined = undefined; getId(): string { return this.config.id; @@ -58,6 +67,19 @@ export class PluginImpl< return extension.expose(this); } + __experimentalReconfigure(options: PluginInputOptions): void { + if (this.config.__experimentalConfigure) { + this.options = this.config.__experimentalConfigure(options); + } + } + + getPluginOptions(): {} { + if (this.config.__experimentalConfigure && !this.options) { + this.options = this.config.__experimentalConfigure(); + } + return this.options ?? {}; + } + toString() { return `plugin{${this.config.id}}`; } @@ -72,8 +94,9 @@ export class PluginImpl< export function createPlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, + PluginInputOptions extends {} = {}, >( - config: PluginConfig, -): BackstagePlugin { + config: PluginConfig, +): BackstagePlugin { return new PluginImpl(config); } diff --git a/packages/core-plugin-api/src/plugin/index.ts b/packages/core-plugin-api/src/plugin/index.ts index 95f5a6b219..7d088ef823 100644 --- a/packages/core-plugin-api/src/plugin/index.ts +++ b/packages/core-plugin-api/src/plugin/index.ts @@ -15,6 +15,7 @@ */ export { createPlugin } from './Plugin'; + export type { AnyExternalRoutes, AnyRoutes, diff --git a/packages/core-plugin-api/src/plugin/types.ts b/packages/core-plugin-api/src/plugin/types.ts index d2dad6f639..37ce6c9e7c 100644 --- a/packages/core-plugin-api/src/plugin/types.ts +++ b/packages/core-plugin-api/src/plugin/types.ts @@ -15,7 +15,7 @@ */ import { RouteRef, SubRouteRef, ExternalRouteRef } from '../routing'; -import { AnyApiFactory } from '../apis/system'; +import { AnyApiFactory } from '../apis'; /** * Plugin extension type. @@ -52,6 +52,7 @@ export type AnyExternalRoutes = { [name: string]: ExternalRouteRef }; export type BackstagePlugin< Routes extends AnyRoutes = {}, ExternalRoutes extends AnyExternalRoutes = {}, + PluginInputOptions extends {} = {}, > = { getId(): string; getApis(): Iterable; @@ -62,6 +63,7 @@ export type BackstagePlugin< provide(extension: Extension): T; routes: Routes; externalRoutes: ExternalRoutes; + __experimentalReconfigure(options: PluginInputOptions): void; }; /** @@ -82,12 +84,14 @@ export type PluginFeatureFlagConfig = { export type PluginConfig< Routes extends AnyRoutes, ExternalRoutes extends AnyExternalRoutes, + PluginInputOptions extends {}, > = { id: string; apis?: Iterable; routes?: Routes; externalRoutes?: ExternalRoutes; featureFlags?: PluginFeatureFlagConfig[]; + __experimentalConfigure?(options?: PluginInputOptions): {}; }; /** diff --git a/packages/create-app/CHANGELOG.md b/packages/create-app/CHANGELOG.md index fd8aa38def..51e9fa0987 100644 --- a/packages/create-app/CHANGELOG.md +++ b/packages/create-app/CHANGELOG.md @@ -1,5 +1,86 @@ # @backstage/create-app +## 0.4.30 + +### Patch Changes + +- 73cee58fc2: Bumped create-app version. +- f762386d48: Bumped create-app version. +- b162bbf464: Bumped create-app version. +- db76fc6255: The `better-sqlite3` dependency has been moved back to production `"dependencies"` in `packages/backend/package.json`, with instructions in the Dockerfile to move it to `"devDependencies"` if desired. There is no need to apply this change to existing apps, unless you want your production image to have SQLite available as a database option. +- ab9edd8b58: Updated backend to write stack trace when the backend fails to start up. + + To apply this change to your Backstage installation, make the following change to `packages/backend/src/index.ts` + + ```diff + cors: + origin: http://localhost:3000 + - console.error(`Backend failed to start up, ${error}`); + + console.error('Backend failed to start up', error); + ``` + +- 0174a0a022: Add `PATCH` and `HEAD` to the `Access-Control-Allow-Methods`. + + To apply this change to your Backstage installation make the following change to your `app-config.yaml` + + ```diff + cors: + origin: http://localhost:3000 + - methods: [GET, POST, PUT, DELETE] + + methods: [GET, POST, PUT, DELETE, PATCH, HEAD] + ``` + +## 0.4.30-next.3 + +### Patch Changes + +- Bumped create-app version. + +## 0.4.30-next.2 + +### Patch Changes + +- 0174a0a022: Add `PATCH` and `HEAD` to the `Access-Control-Allow-Methods`. + + To apply this change to your Backstage installation make the following change to your `app-config.yaml` + + ```diff + cors: + origin: http://localhost:3000 + - methods: [GET, POST, PUT, DELETE] + + methods: [GET, POST, PUT, DELETE, PATCH, HEAD] + ``` + +## 0.4.30-next.1 + +### Patch Changes + +- Bumped create-app version. + +## 0.4.30-next.0 + +### Patch Changes + +- Bumped create-app version. + +## 0.4.29 + +### Patch Changes + +- f281ad17c0: Adds the ability to define the Backstage app name using a `BACKSTAGE_APP_NAME` + environment variable when running `create-app`. +- c92deffe39: Bumped create-app version. +- 0e967f188b: Bumped create-app version. +- bc87604c26: Added an explicit `node-gyp` dependency to the root `package.json`. This is to work around a bug in older versions of `node-gyp` that causes Python execution to fail on macOS. + + You can add this workaround to your existing project by adding `node-gyp` as a `devDependency` in your root `package.json` file: + + ```diff + "devDependencies": { + + "node-gyp": "^9.0.0" + }, + ``` + ## 0.4.29-next.3 ### Patch Changes diff --git a/packages/create-app/package.json b/packages/create-app/package.json index abb7f1fdd8..be2df5752a 100644 --- a/packages/create-app/package.json +++ b/packages/create-app/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/create-app", "description": "A CLI that helps you create your own Backstage app", - "version": "0.4.29-next.3", + "version": "0.4.30", "private": false, "publishConfig": { "access": "public" diff --git a/packages/create-app/templates/default-app/app-config.yaml.hbs b/packages/create-app/templates/default-app/app-config.yaml.hbs index cd6998de69..4a058deefd 100644 --- a/packages/create-app/templates/default-app/app-config.yaml.hbs +++ b/packages/create-app/templates/default-app/app-config.yaml.hbs @@ -24,9 +24,9 @@ backend: # Default Helmet Content-Security-Policy values can be removed by setting the key to false cors: origin: http://localhost:3000 - methods: [GET, POST, PUT, DELETE] + methods: [GET, HEAD, PATCH, POST, PUT, DELETE] credentials: true - # This is for local developement only, it is not recommended to use this in production + # This is for local development only, it is not recommended to use this in production # The production database configuration is stored in app-config.production.yaml database: client: better-sqlite3 diff --git a/packages/create-app/templates/default-app/packages/backend/Dockerfile b/packages/create-app/templates/default-app/packages/backend/Dockerfile index a5773aa0f8..682798b826 100644 --- a/packages/create-app/templates/default-app/packages/backend/Dockerfile +++ b/packages/create-app/templates/default-app/packages/backend/Dockerfile @@ -11,24 +11,30 @@ FROM node:16-bullseye-slim -WORKDIR /app - -# install sqlite3 dependencies, you can skip this if you don't use sqlite3 in the image +# Install sqlite3 dependencies. You can skip this if you don't use sqlite3 in the image, +# in which case you should also move better-sqlite3 to "devDependencies" in package.json. RUN apt-get update && \ apt-get install -y --no-install-recommends libsqlite3-dev python3 build-essential && \ rm -rf /var/lib/apt/lists/* && \ yarn config set python /usr/bin/python3 +# From here on we use the least-privileged `node` user to run the backend. +USER node +WORKDIR /app + +# This switches many Node.js dependencies to production mode. +ENV NODE_ENV production + # Copy repo skeleton first, to avoid unnecessary docker cache invalidation. # The skeleton contains the package.json of each package in the monorepo, # and along with yarn.lock and the root package.json, that's enough to run yarn install. -COPY yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./ +COPY --chown=node:node yarn.lock package.json packages/backend/dist/skeleton.tar.gz ./ RUN tar xzf skeleton.tar.gz && rm skeleton.tar.gz RUN yarn install --frozen-lockfile --production --network-timeout 300000 && rm -rf "$(yarn cache dir)" # Then copy the rest of the backend bundle, along with any other files we might want. -COPY packages/backend/dist/bundle.tar.gz app-config*.yaml ./ +COPY --chown=node:node packages/backend/dist/bundle.tar.gz app-config*.yaml ./ RUN tar xzf bundle.tar.gz && rm bundle.tar.gz CMD ["node", "packages/backend", "--config", "app-config.yaml", "--config", "app-config.production.yaml"] diff --git a/packages/create-app/templates/default-app/packages/backend/package.json.hbs b/packages/create-app/templates/default-app/packages/backend/package.json.hbs index 3bd070ee9b..3853911c7f 100644 --- a/packages/create-app/templates/default-app/packages/backend/package.json.hbs +++ b/packages/create-app/templates/default-app/packages/backend/package.json.hbs @@ -33,6 +33,7 @@ "@backstage/plugin-search-backend-module-pg": "^{{version '@backstage/plugin-search-backend-module-pg'}}", "@backstage/plugin-search-backend-node": "^{{version '@backstage/plugin-search-backend-node'}}", "@backstage/plugin-techdocs-backend": "^{{version '@backstage/plugin-techdocs-backend'}}", + "better-sqlite3": "^7.5.0", "dockerode": "^3.3.1", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -44,8 +45,7 @@ "@types/dockerode": "^3.3.0", "@types/express-serve-static-core": "^4.17.5", "@types/express": "^4.17.6", - "@types/luxon": "^2.0.4", - "better-sqlite3": "^7.5.0" + "@types/luxon": "^2.0.4" }, "files": [ "dist" diff --git a/packages/create-app/templates/default-app/packages/backend/src/index.ts b/packages/create-app/templates/default-app/packages/backend/src/index.ts index 70bc66bcdd..ef05fa50ee 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/index.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/index.ts @@ -104,6 +104,6 @@ async function main() { module.hot?.accept(); main().catch(error => { - console.error(`Backend failed to start up, ${error}`); + console.error('Backend failed to start up', error); process.exit(1); }); diff --git a/packages/create-app/templates/default-app/packages/backend/src/plugins/auth.ts b/packages/create-app/templates/default-app/packages/backend/src/plugins/auth.ts index 159116d7b8..77eb6aae21 100644 --- a/packages/create-app/templates/default-app/packages/backend/src/plugins/auth.ts +++ b/packages/create-app/templates/default-app/packages/backend/src/plugins/auth.ts @@ -25,7 +25,7 @@ export default async function createPlugin( // This particular resolver makes all users share a single "guest" identity. // It should only be used for testing and trying out Backstage. // - // If you want to use a production ready resolver you can switch to the + // If you want to use a production ready resolver you can switch to // the one that is commented out below, it looks up a user entity in the // catalog using the GitHub username of the authenticated user. // That resolver requires you to have user entities populated in the catalog, diff --git a/packages/dev-utils/CHANGELOG.md b/packages/dev-utils/CHANGELOG.md index 7f89910f3b..34adb63d3c 100644 --- a/packages/dev-utils/CHANGELOG.md +++ b/packages/dev-utils/CHANGELOG.md @@ -1,5 +1,56 @@ # @backstage/dev-utils +## 1.0.5 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/app-defaults@1.0.5 + - @backstage/core-app-api@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/test-utils@1.1.3 + +## 1.0.5-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/app-defaults@1.0.5-next.1 + - @backstage/integration-react@1.1.3-next.1 + +## 1.0.5-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/app-defaults@1.0.5-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/test-utils@1.1.3-next.0 + +## 1.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/app-defaults@1.0.4 + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/test-utils@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 1.0.4-next.3 ### Patch Changes diff --git a/packages/dev-utils/package.json b/packages/dev-utils/package.json index 271d7b2e1b..07c51dc8ae 100644 --- a/packages/dev-utils/package.json +++ b/packages/dev-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/dev-utils", "description": "Utilities for developing Backstage plugins.", - "version": "1.0.4-next.3", + "version": "1.0.5", "private": false, "publishConfig": { "access": "public", @@ -33,15 +33,15 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/app-defaults": "^1.0.4-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/integration-react": "^1.1.2-next.3", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/test-utils": "^1.1.2-next.2", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/app-defaults": "^1.0.5", + "@backstage/core-app-api": "^1.0.5", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/catalog-model": "^1.1.0", + "@backstage/integration-react": "^1.1.3", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/test-utils": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@testing-library/jest-dom": "^5.10.1", @@ -59,7 +59,7 @@ "react-dom": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/jest": "^26.0.7", "@types/node": "^16.0.0" }, diff --git a/packages/e2e-test/package.json b/packages/e2e-test/package.json index 333ac09b23..02f013e8a3 100644 --- a/packages/e2e-test/package.json +++ b/packages/e2e-test/package.json @@ -40,7 +40,7 @@ "fs-extra": "10.1.0", "handlebars": "^4.7.3", "pgtools": "^0.3.0", - "puppeteer": "^15.0.0", + "puppeteer": "^16.0.0", "tree-kill": "^1.2.2", "ts-node": "^10.0.0" }, diff --git a/packages/errors/CHANGELOG.md b/packages/errors/CHANGELOG.md index b7d912f5ab..bb3eba0249 100644 --- a/packages/errors/CHANGELOG.md +++ b/packages/errors/CHANGELOG.md @@ -1,5 +1,17 @@ # @backstage/errors +## 1.1.0 + +### Minor Changes + +- 6d61b44466: The `ResponseError.fromResponse` now accepts a more narrow response type, in order to avoid incompatibilities between different fetch implementations. + + The `response` property of `ResponseError` has also been narrowed to a new `ConsumedResponse` type that omits all the properties for consuming the body of the response. This is not considered a breaking change as it was always an error to try to consume the body of the response. + +### Patch Changes + +- c1a8bbf5e5: Inline the type of `ConsumedResponse.headers` and tweaked it to be the intersection of the built-in type and `node-fetch` type. + ## 1.1.0-next.0 ### Minor Changes diff --git a/packages/errors/package.json b/packages/errors/package.json index 01f1137eeb..8bd53e0848 100644 --- a/packages/errors/package.json +++ b/packages/errors/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/errors", "description": "Common utilities for error handling within Backstage", - "version": "1.1.0-next.0", + "version": "1.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -38,7 +38,7 @@ "serialize-error": "^8.0.1" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.1", + "@backstage/cli": "^0.18.1-next.0", "@types/jest": "^26.0.7" }, "files": [ diff --git a/packages/integration-react/CHANGELOG.md b/packages/integration-react/CHANGELOG.md index cf7480ad77..89fbb56619 100644 --- a/packages/integration-react/CHANGELOG.md +++ b/packages/integration-react/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/integration-react +## 1.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 1.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 1.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 1.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/theme@0.2.16 + ## 1.1.2-next.3 ### Patch Changes diff --git a/packages/integration-react/package.json b/packages/integration-react/package.json index fddc3a0894..a75d63725b 100644 --- a/packages/integration-react/package.json +++ b/packages/integration-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration-react", "description": "Frontend package for managing integrations towards external systems", - "version": "1.1.2-next.3", + "version": "1.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -25,10 +25,10 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/integration": "^1.3.0", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -38,15 +38,15 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", - "msw": "^0.44.0", + "msw": "^0.45.0", "cross-fetch": "^3.1.5" }, "files": [ diff --git a/packages/integration/CHANGELOG.md b/packages/integration/CHANGELOG.md index edfb621431..57bb9297ba 100644 --- a/packages/integration/CHANGELOG.md +++ b/packages/integration/CHANGELOG.md @@ -1,5 +1,69 @@ # @backstage/integration +## 1.3.0 + +### Minor Changes + +- 593dea6710: Add support for Basic Auth for Bitbucket Server. +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer + +### Patch Changes + +- 163243a4d1: Handle incorrect return type from Octokit paginate plugin to resolve reading URLs from GitHub +- c4b460a47d: Avoid double encoding of the file path in `getBitbucketDownloadUrl` +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- 1f27d83933: Fixed bug in getGitLabFileFetchUrl where a target whose path did not contain the + `/-/` scope would result in a fetch URL that did not support + private-token-based authentication. + +## 1.3.0-next.1 + +### Minor Changes + +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer + +### Patch Changes + +- 1f27d83933: Fixed bug in getGitLabFileFetchUrl where a target whose path did not contain the + `/-/` scope would result in a fetch URL that did not support + private-token-based authentication. + +## 1.3.0-next.0 + +### Minor Changes + +- 593dea6710: Add support for Basic Auth for Bitbucket Server. + +### Patch Changes + +- 163243a4d1: Handle incorrect return type from Octokit paginate plugin to resolve reading URLs from GitHub +- c4b460a47d: Avoid double encoding of the file path in `getBitbucketDownloadUrl` +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. + +## 1.2.2 + +### Patch Changes + +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 1f29047bad: Updated dependency `@octokit/auth-app` to `^4.0.0`. +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 8829e175f2: Allow frontend visibility for `integrations` itself. +- 954a94f52f: Support self-hosted gitlab installations with relative URL. +- 4df3390795: Avoid double encoding of the file path in `getBitbucketServerDownloadUrl` +- Updated dependencies + - @backstage/errors@1.1.0 + ## 1.2.2-next.3 ### Patch Changes diff --git a/packages/integration/api-report.md b/packages/integration/api-report.md index 8d8d017095..cf52bec65b 100644 --- a/packages/integration/api-report.md +++ b/packages/integration/api-report.md @@ -150,6 +150,8 @@ export type BitbucketServerIntegrationConfig = { host: string; apiBaseUrl: string; token?: string; + username?: string; + password?: string; }; // @public diff --git a/packages/integration/config.d.ts b/packages/integration/config.d.ts index 22acc5cd70..7c897d637a 100644 --- a/packages/integration/config.d.ts +++ b/packages/integration/config.d.ts @@ -92,6 +92,16 @@ export interface Config { * @visibility secret */ token?: string; + /** + * Username used to authenticate requests with Basic Auth. + * @visibility secret + */ + username?: string; + /** + * Password (or token as password) used to authenticate requests with Basic Auth. + * @visibility secret + */ + password?: string; /** * The base url for the Bitbucket Server API, for example https:///rest/api/1.0 * @visibility frontend diff --git a/packages/integration/package.json b/packages/integration/package.json index 68b6ba369c..31b4bbf5f6 100644 --- a/packages/integration/package.json +++ b/packages/integration/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/integration", "description": "Helpers for managing integrations towards external systems", - "version": "1.2.2-next.3", + "version": "1.3.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,7 +34,7 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", + "@backstage/errors": "^1.1.0", "cross-fetch": "^3.1.5", "git-url-parse": "^12.0.0", "@octokit/rest": "^19.0.3", @@ -43,12 +43,12 @@ "lodash": "^4.17.21" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/config-loader": "^1.1.3-next.1", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/config-loader": "^1.1.3", + "@backstage/test-utils": "^1.1.3", "@types/jest": "^26.0.7", - "@types/luxon": "^2.0.4", - "msw": "^0.44.0" + "@types/luxon": "^3.0.0", + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/packages/integration/src/ScmIntegrations.ts b/packages/integration/src/ScmIntegrations.ts index 3e712cc012..6d745dcf1c 100644 --- a/packages/integration/src/ScmIntegrations.ts +++ b/packages/integration/src/ScmIntegrations.ts @@ -113,9 +113,21 @@ export class ScmIntegrations implements ScmIntegrationRegistry { } byUrl(url: string | URL): ScmIntegration | undefined { - return Object.values(this.byType) + let candidates = Object.values(this.byType) .map(i => i.byUrl(url)) - .find(Boolean); + .filter(Boolean); + + // Do not return deprecated integrations if there are other options + if (candidates.length > 1) { + const filteredCandidates = candidates.filter( + x => !(x instanceof BitbucketIntegration), + ); + if (filteredCandidates.length !== 0) { + candidates = filteredCandidates; + } + } + + return candidates[0]; } byHost(host: string): ScmIntegration | undefined { diff --git a/packages/integration/src/bitbucket/core.test.ts b/packages/integration/src/bitbucket/core.test.ts index 2b16be82d4..23a193e6fe 100644 --- a/packages/integration/src/bitbucket/core.test.ts +++ b/packages/integration/src/bitbucket/core.test.ts @@ -139,6 +139,20 @@ describe('bitbucket core', () => { ); }); + it('does not double encode the filepath', async () => { + const config: BitbucketIntegrationConfig = { + host: 'bitbucket.mycompany.net', + apiBaseUrl: 'https://api.bitbucket.mycompany.net/rest/api/1.0', + }; + const result = await getBitbucketDownloadUrl( + 'https://bitbucket.mycompany.net/projects/backstage/repos/mock/browse/%2Fdocs?at=some-branch', + config, + ); + expect(result).toEqual( + 'https://api.bitbucket.mycompany.net/rest/api/1.0/projects/backstage/repos/mock/archive?format=tgz&at=some-branch&prefix=backstage-mock&path=%2Fdocs', + ); + }); + it('do not add path param if no path is specified for Bitbucket Server', async () => { const defaultBranchResponse = { displayId: 'main', diff --git a/packages/integration/src/bitbucket/core.ts b/packages/integration/src/bitbucket/core.ts index f6018ad27a..5c5533155d 100644 --- a/packages/integration/src/bitbucket/core.ts +++ b/packages/integration/src/bitbucket/core.ts @@ -100,7 +100,9 @@ export async function getBitbucketDownloadUrl( // path will limit the downloaded content // /docs will only download the docs folder and everything below it // /docs/index.md will download the docs folder and everything below it - const path = filepath ? `&path=${encodeURIComponent(filepath)}` : ''; + const path = filepath + ? `&path=${encodeURIComponent(decodeURIComponent(filepath))}` + : ''; const archiveUrl = isHosted ? `${protocol}://${resource}/${project}/${repoName}/get/${branch}.tar.gz` : `${config.apiBaseUrl}/projects/${project}/repos/${repoName}/archive?format=tgz&at=${branch}&prefix=${project}-${repoName}${path}`; diff --git a/packages/integration/src/bitbucketServer/BitbucketServerIntegration.test.ts b/packages/integration/src/bitbucketServer/BitbucketServerIntegration.test.ts index 24d7935e72..00b5e21316 100644 --- a/packages/integration/src/bitbucketServer/BitbucketServerIntegration.test.ts +++ b/packages/integration/src/bitbucketServer/BitbucketServerIntegration.test.ts @@ -44,31 +44,58 @@ describe('BitbucketServerIntegration', () => { expect(integration.title).toBe('h.com'); }); - it('resolves url line number correctly', () => { + it('resolves url', () => { const integration = new BitbucketServerIntegration({ host: 'h.com', } as any); expect( integration.resolveUrl({ - url: './a.yaml', - base: 'https://h.com/my-owner/my-project/src/master/README.md', - lineNumber: 14, + url: './README.md', + base: 'https://h.com/projects/my-project/repos/my-repo/browse/?at=master', }), - ).toBe('https://h.com/my-owner/my-project/src/master/a.yaml#a.yaml-14'); + ).toBe( + 'https://h.com/projects/my-project/repos/my-repo/browse/README.md?at=master', + ); }); - it('resolve edit URL', () => { + it('resolves url with line number', () => { + const integration = new BitbucketServerIntegration({ + host: 'h.com', + } as any); + + expect( + integration.resolveUrl({ + url: './README.md', + base: 'https://h.com/projects/my-project/repos/my-repo/browse/?at=master', + lineNumber: 14, + }), + ).toBe( + 'https://h.com/projects/my-project/repos/my-repo/browse/README.md?at=master#14', + ); + }); + + it('resolves edit url', () => { const integration = new BitbucketServerIntegration({ host: 'h.com', } as any); expect( integration.resolveEditUrl( - 'https://h.com/my-owner/my-project/src/master/README.md', + 'https://h.com/projects/my-project/repos/my-repo/browse/README.md', ), - ).toBe( - 'https://h.com/my-owner/my-project/src/master/README.md?mode=edit&spa=0&at=master', - ); + ).toBe('https://h.com/projects/my-project/repos/my-repo/browse/README.md'); + }); + + it('resolves edit url with query params', () => { + const integration = new BitbucketServerIntegration({ + host: 'h.com', + } as any); + + expect( + integration.resolveEditUrl( + 'https://h.com/projects/my-project/repos/my-repo/browse/README.md?at=master', + ), + ).toBe('https://h.com/projects/my-project/repos/my-repo/browse/README.md'); }); }); diff --git a/packages/integration/src/bitbucketServer/BitbucketServerIntegration.ts b/packages/integration/src/bitbucketServer/BitbucketServerIntegration.ts index 10055aeddc..01886e16bc 100644 --- a/packages/integration/src/bitbucketServer/BitbucketServerIntegration.ts +++ b/packages/integration/src/bitbucketServer/BitbucketServerIntegration.ts @@ -14,7 +14,6 @@ * limitations under the License. */ -import parseGitUrl from 'git-url-parse'; import { basicIntegrations, defaultScmResolveUrl } from '../helpers'; import { ScmIntegration, ScmIntegrationsFactory } from '../types'; import { @@ -63,12 +62,11 @@ export class BitbucketServerIntegration implements ScmIntegration { }): string { const resolved = defaultScmResolveUrl(options); - // Bitbucket Server line numbers use the syntax #example.txt-42, rather than #L42 + // Bitbucket Server line numbers use the syntax #42, rather than #L42 if (options.lineNumber) { const url = new URL(resolved); - const filename = url.pathname.split('/').slice(-1)[0]; - url.hash = `${filename}-${options.lineNumber}`; + url.hash = options.lineNumber.toString(); return url.toString(); } @@ -76,14 +74,11 @@ export class BitbucketServerIntegration implements ScmIntegration { } resolveEditUrl(url: string): string { - const urlData = parseGitUrl(url); - const editUrl = new URL(url); - - editUrl.searchParams.set('mode', 'edit'); - // TODO: Not sure what spa=0 does, at least bitbucket.org doesn't support it - // but this is taken over from the initial implementation. - editUrl.searchParams.set('spa', '0'); - editUrl.searchParams.set('at', urlData.ref); - return editUrl.toString(); + // Bitbucket Server doesn't support deep linking to edit mode, therefore there's nothing to do here. + // We just remove query parameters since they cause issues with TechDocs edit button. + if (url.includes('?')) { + return url.substring(0, url.indexOf('?')); + } + return url; } } diff --git a/packages/integration/src/bitbucketServer/config.test.ts b/packages/integration/src/bitbucketServer/config.test.ts index 83c28f5e9d..985165f23f 100644 --- a/packages/integration/src/bitbucketServer/config.test.ts +++ b/packages/integration/src/bitbucketServer/config.test.ts @@ -55,7 +55,7 @@ describe('readBitbucketServerIntegrationConfig', () => { ); } - it('reads all values', () => { + it('reads all values, token', () => { const output = readBitbucketServerIntegrationConfig( buildConfig({ host: 'a.com', @@ -70,6 +70,23 @@ describe('readBitbucketServerIntegrationConfig', () => { }); }); + it('reads all values, basic auth', () => { + const output = readBitbucketServerIntegrationConfig( + buildConfig({ + host: 'a.com', + apiBaseUrl: 'https://a.com/api', + username: 'u', + password: 'p', + }), + ); + expect(output).toEqual({ + host: 'a.com', + apiBaseUrl: 'https://a.com/api', + username: 'u', + password: 'p', + }); + }); + it('rejects funky configs', () => { const valid: any = { host: 'a.com', diff --git a/packages/integration/src/bitbucketServer/config.ts b/packages/integration/src/bitbucketServer/config.ts index ec7930616c..2f93bdeb07 100644 --- a/packages/integration/src/bitbucketServer/config.ts +++ b/packages/integration/src/bitbucketServer/config.ts @@ -46,6 +46,24 @@ export type BitbucketServerIntegrationConfig = { * If no token is specified, anonymous access is used. */ token?: string; + + /** + * The credentials for Basic Authentication for requests to a Bitbucket Server provider. + * + * If `token` was provided, it will be preferred. + * + * See https://developer.atlassian.com/server/bitbucket/how-tos/command-line-rest/#authentication + */ + username?: string; + + /** + * The credentials for Basic Authentication for requests to a Bitbucket Server provider. + * + * If `token` was provided, it will be preferred. + * + * See https://developer.atlassian.com/server/bitbucket/how-tos/command-line-rest/#authentication + */ + password?: string; }; /** @@ -60,6 +78,8 @@ export function readBitbucketServerIntegrationConfig( const host = config.getString('host'); let apiBaseUrl = config.getOptionalString('apiBaseUrl'); const token = config.getOptionalString('token'); + const username = config.getOptionalString('username'); + const password = config.getOptionalString('password'); if (!isValidHost(host)) { throw new Error( @@ -77,6 +97,8 @@ export function readBitbucketServerIntegrationConfig( host, apiBaseUrl, token, + username, + password, }; } diff --git a/packages/integration/src/bitbucketServer/core.test.ts b/packages/integration/src/bitbucketServer/core.test.ts index 076a2c7a4f..de18dcd821 100644 --- a/packages/integration/src/bitbucketServer/core.test.ts +++ b/packages/integration/src/bitbucketServer/core.test.ts @@ -36,7 +36,13 @@ describe('bitbucketServer core', () => { apiBaseUrl: '', token: 'A', }; - const withoutToken: BitbucketServerIntegrationConfig = { + const withBasicAuth: BitbucketServerIntegrationConfig = { + host: '', + apiBaseUrl: '', + username: 'u', + password: 'p', + }; + const withoutCredentials: BitbucketServerIntegrationConfig = { host: '', apiBaseUrl: '', }; @@ -45,7 +51,11 @@ describe('bitbucketServer core', () => { .Authorization, ).toEqual('Bearer A'); expect( - (getBitbucketServerRequestOptions(withoutToken).headers as any) + (getBitbucketServerRequestOptions(withBasicAuth).headers as any) + .Authorization, + ).toEqual('Basic dTpw'); + expect( + (getBitbucketServerRequestOptions(withoutCredentials).headers as any) .Authorization, ).toBeUndefined(); }); diff --git a/packages/integration/src/bitbucketServer/core.ts b/packages/integration/src/bitbucketServer/core.ts index 0c57b0d3ed..5fca2aba68 100644 --- a/packages/integration/src/bitbucketServer/core.ts +++ b/packages/integration/src/bitbucketServer/core.ts @@ -140,6 +140,10 @@ export function getBitbucketServerRequestOptions( if (config.token) { headers.Authorization = `Bearer ${config.token}`; } + if (config.username && config.password) { + const buffer = Buffer.from(`${config.username}:${config.password}`, 'utf8'); + headers.Authorization = `Basic ${buffer.toString('base64')}`; + } return { headers, diff --git a/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.test.ts b/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.test.ts index 246a859b7a..d738edf417 100644 --- a/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.test.ts +++ b/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.test.ts @@ -20,6 +20,7 @@ const octokit = { paginate: async (fn: any) => (await fn()).data, apps: { listInstallations: jest.fn(), + listReposAccessibleToInstallation: jest.fn(), createInstallationAccessToken: jest.fn(), }, }; @@ -325,4 +326,78 @@ describe('SingleInstanceGithubCredentialsProvider tests', () => { expect(headers).toEqual({ Authorization: 'Bearer secret_token' }); expect(token).toEqual('secret_token'); }); + + it('should not throw when paginate response is an array of repositories', async () => { + const repoName = 'foobar'; + octokit.apps.listInstallations.mockResolvedValue({ + headers: { + etag: '123', + }, + data: [ + { + id: 1, + repository_selection: 'all', + account: { + login: 'backstage', + }, + }, + ], + } as RestEndpointMethodTypes['apps']['listInstallations']['response']); + + octokit.apps.createInstallationAccessToken.mockResolvedValueOnce({ + data: { + expires_at: DateTime.local().plus({ hours: 1 }).toString(), + token: 'secret_token', + repository_selection: 'selected', + }, + } as RestEndpointMethodTypes['apps']['createInstallationAccessToken']['response']); + + octokit.apps.listReposAccessibleToInstallation.mockReturnValue({ + data: [{ name: repoName }], + } as unknown as RestEndpointMethodTypes['apps']['listReposAccessibleToInstallation']['response']); + + await expect( + github.getCredentials({ + url: `https://github.com/backstage/${repoName}`, + }), + ).resolves.not.toThrow(); + }); + + it('should not throw when paginate response is an object with a property containing an array of repositories', async () => { + const repoName = 'foobar'; + octokit.apps.listInstallations.mockResolvedValue({ + headers: { + etag: '123', + }, + data: [ + { + id: 1, + repository_selection: 'all', + account: { + login: 'backstage', + }, + }, + ], + } as RestEndpointMethodTypes['apps']['listInstallations']['response']); + + octokit.apps.createInstallationAccessToken.mockResolvedValueOnce({ + data: { + expires_at: DateTime.local().plus({ hours: 1 }).toString(), + token: 'secret_token', + repository_selection: 'selected', + }, + } as RestEndpointMethodTypes['apps']['createInstallationAccessToken']['response']); + + octokit.apps.listReposAccessibleToInstallation.mockReturnValue({ + data: { + repositories: [{ name: repoName }], + }, + } as RestEndpointMethodTypes['apps']['listReposAccessibleToInstallation']['response']); + + await expect( + github.getCredentials({ + url: `https://github.com/backstage/${repoName}`, + }), + ).resolves.not.toThrow(); + }); }); diff --git a/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts b/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts index e56c1521dd..2fd2e7f7dc 100644 --- a/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts +++ b/packages/integration/src/github/SingleInstanceGithubCredentialsProvider.ts @@ -119,7 +119,10 @@ class GithubAppManager { const repos = await installationClient.paginate( installationClient.apps.listReposAccessibleToInstallation, ); - const hasRepo = repos.repositories.some(repository => { + // The return type of the paginate method is incorrect. + const repositories: RestEndpointMethodTypes['apps']['listReposAccessibleToInstallation']['response']['data']['repositories'] = + repos.repositories ?? repos; + const hasRepo = repositories.some(repository => { return repository.name === repo; }); if (!hasRepo) { diff --git a/packages/integration/src/gitlab/core.test.ts b/packages/integration/src/gitlab/core.test.ts index d043aba55a..98fd9b7c13 100644 --- a/packages/integration/src/gitlab/core.test.ts +++ b/packages/integration/src/gitlab/core.test.ts @@ -28,19 +28,15 @@ describe('gitlab core', () => { beforeEach(() => { worker.use( - rest.get('*/api/v4/projects/:name', (_, res, ctx) => + rest.get('*/api/v4/projects/group%2Fproject', (_, res, ctx) => + res(ctx.status(200), ctx.json({ id: 12345 })), + ), + rest.get('*/api/v4/projects/group%2Fsubgroup%2Fproject', (_, res, ctx) => res(ctx.status(200), ctx.json({ id: 12345 })), ), ); }); - const configWithToken: GitLabIntegrationConfig = { - host: 'gitlab.com', - token: '0123456789', - apiBaseUrl: '', - baseUrl: '', - }; - const configWithNoToken: GitLabIntegrationConfig = { host: 'gitlab.com', apiBaseUrl: '', @@ -61,163 +57,133 @@ describe('gitlab core', () => { baseUrl: 'https://gitlab.mycompany.com', }; - describe('getGitLabFileFetchUrl with .yaml extension', () => { - it.each([ - // Project URLs - { - config: configWithNoToken, - url: 'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml', - result: - 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch', - }, - { - config: configSelfHosteWithRelativePath, - url: 'https://gitlab.mycompany.com/gitlab/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml', - result: - 'https://gitlab.mycompany.com/gitlab/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch', - }, - { - config: configSelfHostedWithoutRelativePath, - url: 'https://gitlab.mycompany.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yaml', - result: - 'https://gitlab.mycompany.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yaml/raw?ref=branch', - }, - { - config: configWithNoToken, - // Works with non URI encoded link - url: 'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file with spaces.yaml', - result: - 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile%20with%20spaces.yaml/raw?ref=branch', - }, - { - config: configSelfHosteWithRelativePath, - url: 'https://gitlab.mycompany.com/gitlab/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file with spaces.yaml', - result: - 'https://gitlab.mycompany.com/gitlab/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile%20with%20spaces.yaml/raw?ref=branch', - }, - { - config: configSelfHostedWithoutRelativePath, - url: 'https://gitlab.mycompany.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file with spaces.yaml', - result: - 'https://gitlab.mycompany.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile%20with%20spaces.yaml/raw?ref=branch', - }, - { - config: configWithNoToken, - url: 'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path%20with%20spaces/to/file.yaml', - result: - 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%20with%20spaces%2Fto%2Ffile.yaml/raw?ref=branch', - }, - { - config: configWithToken, - url: 'https://gitlab.example.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path%20with%20spaces/to/file.yaml', - result: - 'https://gitlab.example.com/api/v4/projects/12345/repository/files/my%2Fpath%20with%20spaces%2Fto%2Ffile.yaml/raw?ref=branch', - }, - { - config: configWithNoToken, - url: 'https://gitlab.com/groupA/teams/teamA/repoA/-/blob/branch/my/path%20with%20spaces/to/file.yaml', // Repo not in subgroup - result: - 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%20with%20spaces%2Fto%2Ffile.yaml/raw?ref=branch', - }, - // Raw URLs - { - config: configWithNoToken, - url: 'https://gitlab.example.com/a/b/blob/master/c.yaml', - result: 'https://gitlab.example.com/a/b/raw/master/c.yaml', - }, - { - config: configWithNoToken, - url: 'https://gitlab.example.com/a/b/repo/blob/master/c.yaml', - result: 'https://gitlab.example.com/a/b/repo/raw/master/c.yaml', - }, - { - config: configWithNoToken, - url: 'https://gitlab.example.com/a/blob/blob/master/c.yaml', - result: 'https://gitlab.example.com/a/blob/raw/master/c.yaml', - }, - { - config: configWithNoToken, - url: 'https://gitlab.example.com/a/b/blob/blob/c.yaml', - result: 'https://gitlab.example.com/a/b/raw/blob/c.yaml', - }, - { - config: configWithNoToken, - url: 'https://gitlab.example.com/a//blob/blob/c.yaml', - result: 'https://gitlab.example.com/a/blob/raw/c.yaml', - }, - ])('should handle happy path %#', async ({ config, url, result }) => { - await expect(getGitLabFileFetchUrl(url, config)).resolves.toBe(result); - }); - }); + describe('getGitLabFileFetchUrl', () => { + describe('when target has a scoped route', () => { + it('returns a projects API URL', async () => { + const target = + 'https://gitlab.com/group/project/-/blob/branch/folder/file.yaml'; + const fetchUrl = + 'https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile.yaml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configWithNoToken), + ).resolves.toBe(fetchUrl); + }); - describe('getGitLabFileFetchUrl with .yml extension', () => { - it.each([ - // Project URLs - { - config: configWithNoToken, - url: 'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yml', - result: - 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yml/raw?ref=branch', - }, - { - config: configSelfHosteWithRelativePath, - url: 'https://gitlab.mycompany.com/gitlab/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yml', - result: - 'https://gitlab.mycompany.com/gitlab/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yml/raw?ref=branch', - }, - { - config: configSelfHostedWithoutRelativePath, - url: 'https://gitlab.mycompany.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file.yml', - result: - 'https://gitlab.mycompany.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile.yml/raw?ref=branch', - }, - { - config: configWithNoToken, - // Works with non URI encoded link - url: 'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file with spaces.yml', - result: - 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile%20with%20spaces.yml/raw?ref=branch', - }, - { - config: configSelfHosteWithRelativePath, - // Works with non URI encoded link - url: 'https://gitlab.mycompany.com/gitlab/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file with spaces.yml', - result: - 'https://gitlab.mycompany.com/gitlab/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile%20with%20spaces.yml/raw?ref=branch', - }, - { - config: configSelfHostedWithoutRelativePath, - // Works with non URI encoded link - url: 'https://gitlab.mycompany.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path/to/file with spaces.yml', - result: - 'https://gitlab.mycompany.com/api/v4/projects/12345/repository/files/my%2Fpath%2Fto%2Ffile%20with%20spaces.yml/raw?ref=branch', - }, - { - config: configWithNoToken, - url: 'https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path%20with%20spaces/to/file.yml', - result: - 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%20with%20spaces%2Fto%2Ffile.yml/raw?ref=branch', - }, - { - config: configWithToken, - url: 'https://gitlab.example.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/my/path%20with%20spaces/to/file.yml', - result: - 'https://gitlab.example.com/api/v4/projects/12345/repository/files/my%2Fpath%20with%20spaces%2Fto%2Ffile.yml/raw?ref=branch', - }, - { - config: configWithNoToken, - url: 'https://gitlab.com/groupA/teams/teamA/repoA/-/blob/branch/my/path%20with%20spaces/to/file.yml', // Repo not in subgroup - result: - 'https://gitlab.com/api/v4/projects/12345/repository/files/my%2Fpath%20with%20spaces%2Fto%2Ffile.yml/raw?ref=branch', - }, - // Raw URLs - { - config: configWithNoToken, - url: 'https://gitlab.example.com/a/b/blob/master/c.yml', - result: 'https://gitlab.example.com/a/b/raw/master/c.yml', - }, - ])('should handle happy path %#', async ({ config, url, result }) => { - await expect(getGitLabFileFetchUrl(url, config)).resolves.toBe(result); + it('supports folder named "blob"', async () => { + const target = + 'https://gitlab.com/group/project/-/blob/branch/blob/file.yaml'; + const fetchUrl = + 'https://gitlab.com/api/v4/projects/12345/repository/files/blob%2Ffile.yaml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configWithNoToken), + ).resolves.toBe(fetchUrl); + }); + + it('locates projects in subgroups', async () => { + const target = + 'https://gitlab.com/group/subgroup/project/-/blob/branch/folder/file.yaml'; + const fetchUrl = + 'https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile.yaml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configWithNoToken), + ).resolves.toBe(fetchUrl); + }); + + it('supports filename with .yml extension', async () => { + const target = + 'https://gitlab.com/group/project/-/blob/branch/folder/file.yml'; + const fetchUrl = + 'https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile.yml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configWithNoToken), + ).resolves.toBe(fetchUrl); + }); + + it('supports non-URI-encoded target', async () => { + const target = + 'https://gitlab.com/group/project/-/blob/branch/folder/file with spaces.yaml'; + const fetchUrl = + 'https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile%20with%20spaces.yaml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configWithNoToken), + ).resolves.toBe(fetchUrl); + }); + + describe('when gitlab is self-hosted', () => { + it('returns projects API URL', async () => { + const target = + 'https://gitlab.mycompany.com/group/project/-/blob/branch/folder/file.yaml'; + const fetchUrl = + 'https://gitlab.mycompany.com/api/v4/projects/12345/repository/files/folder%2Ffile.yaml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configSelfHostedWithoutRelativePath), + ).resolves.toBe(fetchUrl); + }); + + it('handles non-URI-encoded target', async () => { + const target = + 'https://gitlab.mycompany.com/group/project/-/blob/branch/folder/file with spaces.yaml'; + const fetchUrl = + 'https://gitlab.mycompany.com/api/v4/projects/12345/repository/files/folder%2Ffile%20with%20spaces.yaml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configSelfHostedWithoutRelativePath), + ).resolves.toBe(fetchUrl); + }); + + describe('with a relative path', () => { + it('returns projects API URL', async () => { + const target = + 'https://gitlab.mycompany.com/gitlab/group/project/-/blob/branch/folder/file.yaml'; + const fetchUrl = + 'https://gitlab.mycompany.com/gitlab/api/v4/projects/12345/repository/files/folder%2Ffile.yaml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configSelfHosteWithRelativePath), + ).resolves.toBe(fetchUrl); + }); + + it('handles non-URI-encoded target', async () => { + const target = + 'https://gitlab.mycompany.com/gitlab/group/project/-/blob/branch/folder/file with spaces.yaml'; + const fetchUrl = + 'https://gitlab.mycompany.com/gitlab/api/v4/projects/12345/repository/files/folder%2Ffile%20with%20spaces.yaml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configSelfHosteWithRelativePath), + ).resolves.toBe(fetchUrl); + }); + }); + }); + }); + + describe('when target has an unscoped route', () => { + it('returns projects API URL', async () => { + const target = + 'https://gitlab.com/group/project/blob/branch/folder/file.yaml'; + const fetchUrl = + 'https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile.yaml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configWithNoToken), + ).resolves.toBe(fetchUrl); + }); + + it('supports project in subgroup', async () => { + const target = + 'https://gitlab.com/group/subgroup/project/blob/branch/folder/file.yaml'; + const fetchUrl = + 'https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile.yaml/raw?ref=branch'; + await expect( + getGitLabFileFetchUrl(target, configWithNoToken), + ).resolves.toBe(fetchUrl); + }); + + it('supports repo with branch named "blob"', async () => { + const target = + 'https://gitlab.com/group/project/blob/blob/folder/file.yaml'; + const fetchUrl = + 'https://gitlab.com/api/v4/projects/12345/repository/files/folder%2Ffile.yaml/raw?ref=blob'; + await expect( + getGitLabFileFetchUrl(target, configWithNoToken), + ).resolves.toBe(fetchUrl); + }); }); }); }); diff --git a/packages/integration/src/gitlab/core.ts b/packages/integration/src/gitlab/core.ts index 1fcf15a78f..040ca202d6 100644 --- a/packages/integration/src/gitlab/core.ts +++ b/packages/integration/src/gitlab/core.ts @@ -19,7 +19,6 @@ import { GitLabIntegrationConfig, } from './config'; import fetch from 'cross-fetch'; -import { InputError } from '@backstage/errors'; /** * Given a URL pointing to a file on a provider, returns a URL that is suitable @@ -29,7 +28,7 @@ import { InputError } from '@backstage/errors'; * * Converts * from: https://gitlab.example.com/a/b/blob/master/c.yaml - * to: https://gitlab.example.com/a/b/raw/master/c.yaml + * to: https://gitlab.com/api/v4/projects/projectId/repository/c.yaml?ref=master * -or- * from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath * to: https://gitlab.com/api/v4/projects/projectId/repository/files/filepath?ref=branch @@ -42,15 +41,8 @@ export async function getGitLabFileFetchUrl( url: string, config: GitLabIntegrationConfig, ): Promise { - // TODO(Rugvip): From the old GitlabReaderProcessor; used - // the existence of /-/blob/ to switch the logic. Don't know if this - // makes sense and it might require some more work. - - if (url.includes('/-/blob/')) { - const projectID = await getProjectId(url, config); - return buildProjectUrl(url, projectID, config).toString(); - } - return buildRawUrl(url).toString(); + const projectID = await getProjectId(url, config); + return buildProjectUrl(url, projectID, config).toString(); } /** @@ -70,38 +62,6 @@ export function getGitLabRequestOptions(config: GitLabIntegrationConfig): { }; } -// Converts -// from: https://gitlab.example.com/groupA/teams/repoA/blob/master/c.yaml -// to: https://gitlab.example.com/groupA/teams/repoA/raw/master/c.yaml -export function buildRawUrl(target: string): URL { - try { - const url = new URL(target); - - const splitPath = url.pathname.split('/').filter(Boolean); - - // Check blob existence - const blobIndex = splitPath.indexOf('blob', 2); - if (blobIndex < 2 || blobIndex === splitPath.length - 1) { - throw new InputError('Wrong GitLab URL'); - } - - // Take repo path - const repoPath = splitPath.slice(0, blobIndex); - const restOfPath = splitPath.slice(blobIndex + 1); - - if (!restOfPath.join('/').match(/\.(yaml|yml)$/)) { - throw new InputError('Wrong GitLab URL'); - } - - // Replace 'blob' with 'raw' - url.pathname = [...repoPath, 'raw', ...restOfPath].join('/'); - - return url; - } catch (e) { - throw new InputError(`Incorrect url: ${target}, ${e}`); - } -} - // Converts // from: https://gitlab.com/groupA/teams/teamA/subgroupA/repoA/-/blob/branch/filepath // to: https://gitlab.com/api/v4/projects/projectId/repository/files/filepath?ref=branch @@ -113,7 +73,10 @@ export function buildProjectUrl( try { const url = new URL(target); - const branchAndFilePath = url.pathname.split('/-/blob/')[1]; + const branchAndFilePath = url.pathname + .split('/blob/') + .slice(1) + .join('/blob/'); const [branch, ...filePath] = branchAndFilePath.split('/'); const relativePath = getGitLabIntegrationRelativePath(config); @@ -143,12 +106,12 @@ export async function getProjectId( ): Promise { const url = new URL(target); - if (!url.pathname.includes('/-/blob/')) { + if (!url.pathname.includes('/blob/')) { throw new Error('Please provide full path to yaml file from GitLab'); } try { - let repo = url.pathname.split('/-/blob/')[0]; + let repo = url.pathname.split('/-/blob/')[0].split('/blob/')[0]; // Get gitlab relative path const relativePath = getGitLabIntegrationRelativePath(config); diff --git a/packages/release-manifests/CHANGELOG.md b/packages/release-manifests/CHANGELOG.md index 0d28ee16ad..b00e1c5821 100644 --- a/packages/release-manifests/CHANGELOG.md +++ b/packages/release-manifests/CHANGELOG.md @@ -1,5 +1,12 @@ # @backstage/release-manifests +## 0.0.5 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. + ## 0.0.5-next.0 ### Patch Changes diff --git a/packages/release-manifests/package.json b/packages/release-manifests/package.json index 11dcd08df4..68eef91636 100644 --- a/packages/release-manifests/package.json +++ b/packages/release-manifests/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/release-manifests", "description": "Helper library for receiving release manifests", - "version": "0.0.5-next.0", + "version": "0.0.5", "private": false, "main": "src/index.ts", "types": "src/index.ts", @@ -36,8 +36,8 @@ "cross-fetch": "^3.1.5" }, "devDependencies": { - "@backstage/test-utils": "^1.1.2-next.2", - "msw": "^0.44.0", + "@backstage/test-utils": "^1.1.3-next.0", + "msw": "^0.45.0", "@types/jest": "^26.0.7", "@types/node": "^16.0.0" }, diff --git a/packages/techdocs-cli-embedded-app/CHANGELOG.md b/packages/techdocs-cli-embedded-app/CHANGELOG.md index c7200360c1..85300ab0f7 100644 --- a/packages/techdocs-cli-embedded-app/CHANGELOG.md +++ b/packages/techdocs-cli-embedded-app/CHANGELOG.md @@ -1,5 +1,68 @@ # techdocs-cli-embedded-app +## 0.2.73 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.18.1 + - @backstage/plugin-techdocs@1.3.1 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog@1.5.0 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/app-defaults@1.0.5 + - @backstage/core-app-api@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/test-utils@1.1.3 + +## 0.2.73-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.18.1-next.1 + - @backstage/plugin-techdocs@1.3.1-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/app-defaults@1.0.5-next.1 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-catalog@1.5.0-next.2 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + +## 0.2.73-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog@1.5.0-next.0 + - @backstage/plugin-techdocs@1.3.1-next.0 + - @backstage/cli@0.18.1-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/app-defaults@1.0.5-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/test-utils@1.1.3-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + +## 0.2.72 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/plugin-catalog@1.4.0 + - @backstage/cli@0.18.0 + - @backstage/app-defaults@1.0.4 + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/test-utils@1.1.2 + - @backstage/plugin-techdocs@1.3.0 + - @backstage/theme@0.2.16 + ## 0.2.72-next.3 ### Patch Changes diff --git a/packages/techdocs-cli-embedded-app/package.json b/packages/techdocs-cli-embedded-app/package.json index a66e9a01d8..ea429fa611 100644 --- a/packages/techdocs-cli-embedded-app/package.json +++ b/packages/techdocs-cli-embedded-app/package.json @@ -1,25 +1,25 @@ { "name": "techdocs-cli-embedded-app", - "version": "0.2.72-next.3", + "version": "0.2.73", "private": true, "backstage": { "role": "frontend" }, "bundled": true, "dependencies": { - "@backstage/app-defaults": "^1.0.4-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/app-defaults": "^1.0.5", + "@backstage/catalog-model": "^1.1.0", + "@backstage/cli": "^0.18.1", "@backstage/config": "^1.0.1", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/integration-react": "^1.1.2-next.3", - "@backstage/plugin-catalog": "^1.4.0-next.3", - "@backstage/plugin-techdocs": "^1.2.1-next.3", - "@backstage/plugin-techdocs-react": "^1.0.2-next.2", - "@backstage/test-utils": "^1.1.2-next.2", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/integration-react": "^1.1.3", + "@backstage/plugin-catalog": "^1.5.0", + "@backstage/plugin-techdocs": "^1.3.1", + "@backstage/plugin-techdocs-react": "^1.0.3", + "@backstage/test-utils": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.11.0", "@material-ui/icons": "^4.9.1", "history": "^5.0.0", @@ -30,7 +30,7 @@ "react-use": "^17.2.4" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx index c7328a0487..cc20081198 100644 --- a/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx +++ b/packages/techdocs-cli-embedded-app/src/components/TechDocsPage/TechDocsPage.tsx @@ -55,7 +55,7 @@ export const TechDocsThemeToggle = () => { const appThemeApi = useApi(appThemeApiRef); const classes = useStyles(); const [theme, setTheme] = useState( - (appThemeApi.getActiveThemeId() as Themes) || Themes.LIGHT, + appThemeApi.getActiveThemeId() === Themes.DARK ? Themes.DARK : Themes.LIGHT, ); const themes = { diff --git a/packages/techdocs-cli/CHANGELOG.md b/packages/techdocs-cli/CHANGELOG.md index 3e66248276..27843fbec5 100644 --- a/packages/techdocs-cli/CHANGELOG.md +++ b/packages/techdocs-cli/CHANGELOG.md @@ -1,5 +1,50 @@ # @techdocs/cli +## 1.2.0 + +### Minor Changes + +- 855952db53: Added CLI option `--docker-option` to allow passing additional options to the `docker run` command executed my `serve` and `serve:mkdocs`. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-techdocs-node@1.3.0 + +## 1.2.0-next.2 + +### Minor Changes + +- 855952db53: Added CLI option `--docker-option` to allow passing additional options to the `docker run` command executed my `serve` and `serve:mkdocs`. + +## 1.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + - @backstage/plugin-techdocs-node@1.3.0-next.1 + +## 1.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-techdocs-node@1.2.1-next.0 + +## 1.1.3 + +### Patch Changes + +- a5d73da942: Fix the flag parsing for `legacyCopyReadmeMdToIndexMd` in `techdocs-cli generate` command, and decouple it's logic from the `techdocs-ref` flag. +- 14ce0d9347: Fixed a bug that prevented docker images from being pulled by default when generating TechDocs. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.2.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + ## 1.1.3-next.1 ### Patch Changes diff --git a/packages/techdocs-cli/cli-report.md b/packages/techdocs-cli/cli-report.md index 64b5e9c090..cf5b2caf0f 100644 --- a/packages/techdocs-cli/cli-report.md +++ b/packages/techdocs-cli/cli-report.md @@ -96,6 +96,7 @@ Usage: techdocs-cli serve [options] Options: -i, --docker-image --docker-entrypoint + --docker-option --no-docker --mkdocs-port -v --verbose @@ -110,6 +111,7 @@ Usage: techdocs-cli serve:mkdocs [options] Options: -i, --docker-image --docker-entrypoint + --docker-option --no-docker -p, --port -v --verbose diff --git a/packages/techdocs-cli/package.json b/packages/techdocs-cli/package.json index 00e254d10f..bb8b10fb6f 100644 --- a/packages/techdocs-cli/package.json +++ b/packages/techdocs-cli/package.json @@ -1,7 +1,7 @@ { "name": "@techdocs/cli", "description": "Utility CLI for managing TechDocs sites in Backstage.", - "version": "1.1.3-next.1", + "version": "1.2.0", "private": false, "publishConfig": { "access": "public" @@ -37,7 +37,7 @@ "techdocs-cli": "bin/techdocs-cli" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.1", + "@backstage/cli": "^0.18.1", "@types/commander": "^2.12.2", "@types/fs-extra": "^9.0.6", "@types/http-proxy": "^1.17.4", @@ -62,11 +62,11 @@ "ext": "ts" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.1", - "@backstage/catalog-model": "^1.1.0-next.1", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-model": "^1.1.0", "@backstage/cli-common": "^0.1.9", "@backstage/config": "^1.0.1", - "@backstage/plugin-techdocs-node": "^1.2.0-next.1", + "@backstage/plugin-techdocs-node": "^1.3.0", "@types/dockerode": "^3.3.0", "commander": "^9.1.0", "dockerode": "^3.3.1", diff --git a/packages/techdocs-cli/src/commands/index.ts b/packages/techdocs-cli/src/commands/index.ts index 68e8f88c0b..03772d09d7 100644 --- a/packages/techdocs-cli/src/commands/index.ts +++ b/packages/techdocs-cli/src/commands/index.ts @@ -215,6 +215,10 @@ export function registerCommands(program: Command) { '--docker-entrypoint ', 'Override the image entrypoint', ) + .option( + '--docker-option ', + 'Extra options to pass to the docker run command, e.g. "--add-host=internal.host:192.168.11.12" (can be added multiple times).', + ) .option( '--no-docker', 'Do not use Docker, run `mkdocs serve` in current user environment.', @@ -237,6 +241,10 @@ export function registerCommands(program: Command) { '--docker-entrypoint ', 'Override the image entrypoint', ) + .option( + '--docker-option ', + 'Extra options to pass to the docker run command, e.g. "--add-host=internal.host:192.168.11.12" (can be added multiple times).', + ) .option( '--no-docker', 'Do not use Docker, use MkDocs executable in current user environment.', diff --git a/packages/techdocs-cli/src/commands/serve/mkdocs.ts b/packages/techdocs-cli/src/commands/serve/mkdocs.ts index 511df00a17..9cc0aef3be 100644 --- a/packages/techdocs-cli/src/commands/serve/mkdocs.ts +++ b/packages/techdocs-cli/src/commands/serve/mkdocs.ts @@ -62,6 +62,7 @@ export default async function serveMkdocs(opts: OptionValues) { port: opts.port, dockerImage: opts.dockerImage, dockerEntrypoint: opts.dockerEntrypoint, + dockerOptions: opts.dockerOption, useDocker: opts.docker, stdoutLogFunc: logFunc, stderrLogFunc: logFunc, diff --git a/packages/techdocs-cli/src/commands/serve/serve.ts b/packages/techdocs-cli/src/commands/serve/serve.ts index 454e9ffa55..68d0bbb277 100644 --- a/packages/techdocs-cli/src/commands/serve/serve.ts +++ b/packages/techdocs-cli/src/commands/serve/serve.ts @@ -93,6 +93,7 @@ export default async function serve(opts: OptionValues) { port: opts.mkdocsPort, dockerImage: opts.dockerImage, dockerEntrypoint: opts.dockerEntrypoint, + dockerOptions: opts.dockerOption, useDocker: opts.docker, stdoutLogFunc: mkdocsLogFunc, stderrLogFunc: mkdocsLogFunc, diff --git a/packages/techdocs-cli/src/lib/mkdocsServer.test.ts b/packages/techdocs-cli/src/lib/mkdocsServer.test.ts index 0167dec12b..8484c4e242 100644 --- a/packages/techdocs-cli/src/lib/mkdocsServer.test.ts +++ b/packages/techdocs-cli/src/lib/mkdocsServer.test.ts @@ -64,6 +64,39 @@ describe('runMkdocsServer', () => { expect.objectContaining({}), ); }); + + it('should accept custom docker options', async () => { + await runMkdocsServer({ + dockerOptions: [ + '--add-host=internal.host:192.168.11.12', + '--name', + 'my-techdocs-container', + ], + }); + + expect(run).toHaveBeenCalledWith( + 'docker', + expect.arrayContaining([ + 'run', + '--rm', + '-w', + '/content', + '-v', + `${process.cwd()}:/content`, + '-p', + '8000:8000', + '-it', + '--add-host=internal.host:192.168.11.12', + '--name', + 'my-techdocs-container', + 'spotify/techdocs', + 'serve', + '--dev-addr', + '0.0.0.0:8000', + ]), + expect.objectContaining({}), + ); + }); }); describe('mkdocs', () => { diff --git a/packages/techdocs-cli/src/lib/mkdocsServer.ts b/packages/techdocs-cli/src/lib/mkdocsServer.ts index c0b0cec498..5ca7e47573 100644 --- a/packages/techdocs-cli/src/lib/mkdocsServer.ts +++ b/packages/techdocs-cli/src/lib/mkdocsServer.ts @@ -22,6 +22,7 @@ export const runMkdocsServer = async (options: { useDocker?: boolean; dockerImage?: string; dockerEntrypoint?: string; + dockerOptions?: string[]; stdoutLogFunc?: LogFunc; stderrLogFunc?: LogFunc; }): Promise => { @@ -45,6 +46,7 @@ export const runMkdocsServer = async (options: { ...(options.dockerEntrypoint ? ['--entrypoint', options.dockerEntrypoint] : []), + ...(options.dockerOptions || []), dockerImage, 'serve', '--dev-addr', diff --git a/packages/test-utils/CHANGELOG.md b/packages/test-utils/CHANGELOG.md index 317dc6afa7..4f15c6a665 100644 --- a/packages/test-utils/CHANGELOG.md +++ b/packages/test-utils/CHANGELOG.md @@ -1,5 +1,36 @@ # @backstage/test-utils +## 1.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + - @backstage/core-app-api@1.0.5 + - @backstage/plugin-permission-react@0.4.4 + +## 1.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/plugin-permission-react@0.4.4-next.0 + +## 1.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/theme@0.2.16 + - @backstage/plugin-permission-react@0.4.3 + ## 1.1.2-next.2 ### Patch Changes diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 49553caea7..4a42052d7a 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/test-utils", "description": "Utilities to test Backstage plugins and apps.", - "version": "1.1.2-next.2", + "version": "1.1.3", "private": false, "publishConfig": { "access": "public", @@ -34,11 +34,11 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-permission-common": "^0.6.3-next.1", - "@backstage/plugin-permission-react": "^0.4.3-next.1", - "@backstage/theme": "^0.2.16-next.0", + "@backstage/core-app-api": "^1.0.5", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-permission-common": "^0.6.3", + "@backstage/plugin-permission-react": "^0.4.4", + "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.11.2", @@ -55,10 +55,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/packages/theme/CHANGELOG.md b/packages/theme/CHANGELOG.md index 93b79b0721..dcdcf2a6ae 100644 --- a/packages/theme/CHANGELOG.md +++ b/packages/theme/CHANGELOG.md @@ -1,5 +1,15 @@ # @backstage/theme +## 0.2.16 + +### Patch Changes + +- ff4f56eb49: **DEPRECATED**: The `bursts` object from `BackstagePaletteAdditions` has been depreciated and will be removed in a future release + + The `genPageTheme` function now includes an optional options object with an optional `fontColor` which defaults to white if not provided. + +- 4c09c09102: Adds optional `htmlFontSize` property and also sets typography design tokens for h5 and h6 in base theme. + ## 0.2.16-next.1 ### Patch Changes diff --git a/packages/theme/package.json b/packages/theme/package.json index 4cbd4d2205..4323549ffb 100644 --- a/packages/theme/package.json +++ b/packages/theme/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/theme", "description": "material-ui theme for use with Backstage.", - "version": "0.2.16-next.1", + "version": "0.2.16", "private": false, "publishConfig": { "access": "public", @@ -36,7 +36,7 @@ "@material-ui/core": "^4.12.2" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.2" + "@backstage/cli": "^0.18.1-next.0" }, "files": [ "dist" diff --git a/packages/types/package.json b/packages/types/package.json index d1410631bd..697c9f17f3 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -34,7 +34,7 @@ }, "dependencies": {}, "devDependencies": { - "@backstage/cli": "^0.18.0-next.1", + "@backstage/cli": "^0.18.1-next.0", "@types/zen-observable": "^0.8.0", "zen-observable": "^0.8.15" }, diff --git a/packages/version-bridge/package.json b/packages/version-bridge/package.json index 4b9ce2ed11..37d23238ba 100644 --- a/packages/version-bridge/package.json +++ b/packages/version-bridge/package.json @@ -37,7 +37,7 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.1", + "@backstage/cli": "^0.18.1-next.0", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0" diff --git a/plugins/adr-backend/CHANGELOG.md b/plugins/adr-backend/CHANGELOG.md index 129e6bf56b..a4ad1edfa4 100644 --- a/plugins/adr-backend/CHANGELOG.md +++ b/plugins/adr-backend/CHANGELOG.md @@ -1,5 +1,59 @@ # @backstage/plugin-adr-backend +## 0.2.0 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-adr-common@0.2.0 + - @backstage/integration@1.3.0 + +## 0.2.0-next.1 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-adr-common@0.2.0-next.1 + - @backstage/backend-common@0.15.0-next.2 + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-adr-common@0.1.3-next.0 + +## 0.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/errors@1.1.0 + - @backstage/plugin-adr-common@0.1.2 + ## 0.1.2-next.2 ### Patch Changes diff --git a/plugins/adr-backend/package.json b/plugins/adr-backend/package.json index eb2fcf9ca7..08bc593a60 100644 --- a/plugins/adr-backend/package.json +++ b/plugins/adr-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr-backend", - "version": "0.1.2-next.2", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,14 +29,14 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-adr-common": "^0.1.2-next.1", - "@backstage/plugin-search-common": "^0.3.6-next.0", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-adr-common": "^0.2.0", + "@backstage/plugin-search-common": "^1.0.0", "luxon": "^3.0.0", "marked": "^4.0.14", "winston": "^3.2.1", @@ -44,11 +44,11 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/marked": "^4.0.0", "@types/supertest": "^2.0.8", "supertest": "^6.1.3", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/adr-backend/src/search/DefaultAdrCollatorFactory.ts b/plugins/adr-backend/src/search/DefaultAdrCollatorFactory.ts index e0c90af767..811b52ba82 100644 --- a/plugins/adr-backend/src/search/DefaultAdrCollatorFactory.ts +++ b/plugins/adr-backend/src/search/DefaultAdrCollatorFactory.ts @@ -142,6 +142,7 @@ export class DefaultAdrCollatorFactory implements DocumentCollatorFactory { 'metadata.annotations', 'metadata.name', 'metadata.namespace', + 'metadata.title', ], }, { token }, diff --git a/plugins/adr-backend/src/search/createMadrParser.ts b/plugins/adr-backend/src/search/createMadrParser.ts index 9efd49754a..6b77ec2fa7 100644 --- a/plugins/adr-backend/src/search/createMadrParser.ts +++ b/plugins/adr-backend/src/search/createMadrParser.ts @@ -16,6 +16,7 @@ import { DateTime } from 'luxon'; import { marked } from 'marked'; +import { stringifyEntityRef } from '@backstage/catalog-model'; import { MADR_DATE_FORMAT } from '@backstage/plugin-adr-common'; import { AdrParser } from './types'; @@ -101,6 +102,8 @@ export const createMadrParser = ( text: content, status: adrStatus, date: adrDate, + entityRef: stringifyEntityRef(entity), + entityTitle: entity.metadata.title, location: applyArgsToFormat(locationTemplate, { namespace: entity.metadata.namespace || 'default', kind: entity.kind, diff --git a/plugins/adr-common/CHANGELOG.md b/plugins/adr-common/CHANGELOG.md index e07697118c..baf239d0ab 100644 --- a/plugins/adr-common/CHANGELOG.md +++ b/plugins/adr-common/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-adr-common +## 0.2.0 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + +## 0.2.0-next.1 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/integration@1.2.2 + ## 0.1.2-next.1 ### Patch Changes diff --git a/plugins/adr-common/api-report.md b/plugins/adr-common/api-report.md index 290d984181..0236b355a5 100644 --- a/plugins/adr-common/api-report.md +++ b/plugins/adr-common/api-report.md @@ -10,6 +10,8 @@ import { ScmIntegrationRegistry } from '@backstage/integration'; // @public export interface AdrDocument extends IndexableDocument { date?: string; + entityRef: string; + entityTitle?: string; status?: string; } diff --git a/plugins/adr-common/package.json b/plugins/adr-common/package.json index a0567fb5b8..76058f8a86 100644 --- a/plugins/adr-common/package.json +++ b/plugins/adr-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-adr-common", "description": "Common functionalities for the adr plugin", - "version": "0.1.2-next.1", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,12 +30,12 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.1", - "@backstage/integration": "^1.2.2-next.1", - "@backstage/plugin-search-common": "^0.3.6-next.0" + "@backstage/catalog-model": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-search-common": "^1.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.1" + "@backstage/cli": "^0.18.1" }, "files": [ "dist" diff --git a/plugins/adr-common/src/index.ts b/plugins/adr-common/src/index.ts index 94b6b788c8..c3a048d9d1 100644 --- a/plugins/adr-common/src/index.ts +++ b/plugins/adr-common/src/index.ts @@ -84,6 +84,14 @@ export const madrFilePathFilter: AdrFilePathFilterFn = (path: string) => * @public */ export interface AdrDocument extends IndexableDocument { + /** + * Ref of the entity associated with this ADR + */ + entityRef: string; + /** + * Title of the entity associated with this ADR + */ + entityTitle?: string; /** * ADR status label */ diff --git a/plugins/adr/CHANGELOG.md b/plugins/adr/CHANGELOG.md index 34c81a7f80..f3f92199e4 100644 --- a/plugins/adr/CHANGELOG.md +++ b/plugins/adr/CHANGELOG.md @@ -1,5 +1,85 @@ # @backstage/plugin-adr +## 0.2.0 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-adr-common@0.2.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## 0.2.0-next.2 + +### Minor Changes + +- bfc7c50a09: Display associated entity as a chip in `AdrSearchResultListItem` + + BREAKING: `AdrDocument` now includes a `entityRef` property, if you have a custom `AdrParser` you will have to supply this property in your returned documents + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-adr-common@0.2.0-next.1 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-search-react@1.0.1-next.1 + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-adr-common@0.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + +## 0.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 511f49ee43: Updated dependency `octokit` to `^2.0.0`. +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 7d47e7e512: Track discover event and result rank for `AdrSearchResultListItem` +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/plugin-adr-common@0.1.2 + ## 0.1.2-next.3 ### Patch Changes diff --git a/plugins/adr/api-report.md b/plugins/adr/api-report.md index fbe04b1dc4..ecec0c0dd5 100644 --- a/plugins/adr/api-report.md +++ b/plugins/adr/api-report.md @@ -25,18 +25,13 @@ export const adrPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; // @public export const AdrReader: { - ({ - adr, - decorators, - }: { - adr: string; - decorators?: AdrContentDecorator[] | undefined; - }): JSX.Element; + (props: { adr: string; decorators?: AdrContentDecorator[] }): JSX.Element; decorators: Readonly<{ createRewriteRelativeLinksDecorator(): AdrContentDecorator; createRewriteRelativeEmbedsDecorator(): AdrContentDecorator; @@ -44,23 +39,15 @@ export const AdrReader: { }; // @public -export const AdrSearchResultListItem: ({ - lineClamp, - highlight, - rank, - result, -}: { - lineClamp?: number | undefined; - highlight?: ResultHighlight | undefined; - rank?: number | undefined; +export function AdrSearchResultListItem(props: { + lineClamp?: number; + highlight?: ResultHighlight; + rank?: number; result: AdrDocument; -}) => JSX.Element; +}): JSX.Element; // @public -export const EntityAdrContent: ({ - contentDecorators, - filePathFilterFn, -}: { +export const EntityAdrContent: (props: { contentDecorators?: AdrContentDecorator[] | undefined; filePathFilterFn?: AdrFilePathFilterFn | undefined; }) => JSX.Element; diff --git a/plugins/adr/package.json b/plugins/adr/package.json index 22cb883ae1..bbbc5b1c34 100644 --- a/plugins/adr/package.json +++ b/plugins/adr/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-adr", - "version": "0.1.2-next.3", + "version": "0.2.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,14 +22,15 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/integration-react": "^1.1.2-next.3", - "@backstage/plugin-adr-common": "^0.1.2-next.1", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/plugin-search-common": "^0.3.6-next.0", - "@backstage/plugin-search-react": "^0.2.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/integration-react": "^1.1.3", + "@backstage/plugin-adr-common": "^0.2.0", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/plugin-search-common": "^1.0.0", + "@backstage/plugin-search-react": "^1.0.1", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -44,10 +45,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", @@ -55,7 +56,7 @@ "@types/jest": "*", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/adr/src/components/AdrReader/AdrReader.tsx b/plugins/adr/src/components/AdrReader/AdrReader.tsx index ae7dc6c271..3667d8fd8c 100644 --- a/plugins/adr/src/components/AdrReader/AdrReader.tsx +++ b/plugins/adr/src/components/AdrReader/AdrReader.tsx @@ -32,15 +32,14 @@ import { AdrContentDecorator } from './types'; /** * Component to fetch and render an ADR. + * * @public */ -export const AdrReader = ({ - adr, - decorators, -}: { +export const AdrReader = (props: { adr: string; decorators?: AdrContentDecorator[]; }) => { + const { adr, decorators } = props; const { entity } = useEntity(); const scmIntegrations = useApi(scmIntegrationsApiRef); const adrLocationUrl = getAdrLocationUrl(entity, scmIntegrations); diff --git a/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx b/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx index bd8e4be3cf..37344cecca 100644 --- a/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx +++ b/plugins/adr/src/components/EntityAdrContent/EntityAdrContent.tsx @@ -58,13 +58,11 @@ const useStyles = makeStyles((theme: Theme) => ({ * Component for browsing ADRs on an entity page. * @public */ -export const EntityAdrContent = ({ - contentDecorators, - filePathFilterFn, -}: { +export const EntityAdrContent = (props: { contentDecorators?: AdrContentDecorator[]; filePathFilterFn?: AdrFilePathFilterFn; }) => { + const { contentDecorators, filePathFilterFn } = props; const classes = useStyles(); const { entity } = useEntity(); const rootLink = useRouteRef(rootRouteRef); diff --git a/plugins/adr/src/search/AdrSearchResultListItem.tsx b/plugins/adr/src/search/AdrSearchResultListItem.tsx index 677e39fc11..d76f2cca4e 100644 --- a/plugins/adr/src/search/AdrSearchResultListItem.tsx +++ b/plugins/adr/src/search/AdrSearchResultListItem.tsx @@ -23,9 +23,11 @@ import { ListItemText, makeStyles, } from '@material-ui/core'; +import { parseEntityRef } from '@backstage/catalog-model'; import { Link } from '@backstage/core-components'; import { useAnalytics } from '@backstage/core-plugin-api'; import { AdrDocument } from '@backstage/plugin-adr-common'; +import { humanizeEntityRef } from '@backstage/plugin-catalog-react'; import { ResultHighlight } from '@backstage/plugin-search-common'; import { HighlightedSearchResultText } from '@backstage/plugin-search-react'; @@ -41,20 +43,16 @@ const useStyles = makeStyles({ }); /** - * A component to display a ADR search result + * A component to display an ADR search result. * @public */ -export const AdrSearchResultListItem = ({ - lineClamp = 5, - highlight, - rank, - result, -}: { +export function AdrSearchResultListItem(props: { lineClamp?: number; highlight?: ResultHighlight; rank?: number; result: AdrDocument; -}) => { +}) { + const { lineClamp = 5, highlight, rank, result } = props; const classes = useStyles(); const analytics = useAnalytics(); @@ -104,6 +102,13 @@ export const AdrSearchResultListItem = ({ } /> + {result.status && ( )} @@ -113,4 +118,4 @@ export const AdrSearchResultListItem = ({ ); -}; +} diff --git a/plugins/airbrake-backend/CHANGELOG.md b/plugins/airbrake-backend/CHANGELOG.md index 49d4de7c96..01d44965d8 100644 --- a/plugins/airbrake-backend/CHANGELOG.md +++ b/plugins/airbrake-backend/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-airbrake-backend +## 0.2.8 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## 0.2.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## 0.2.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + ## 0.2.7-next.1 ### Patch Changes diff --git a/plugins/airbrake-backend/package.json b/plugins/airbrake-backend/package.json index 70ed0ddaca..e808c65371 100644 --- a/plugins/airbrake-backend/package.json +++ b/plugins/airbrake-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake-backend", - "version": "0.2.7-next.1", + "version": "0.2.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,7 +22,7 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", + "@backstage/backend-common": "^0.15.0", "@backstage/config": "^1.0.1", "@types/express": "*", "express": "^4.17.1", @@ -33,11 +33,11 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/http-proxy-middleware": "^0.19.3", "@types/supertest": "^2.0.8", "supertest": "^6.1.6", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/airbrake/CHANGELOG.md b/plugins/airbrake/CHANGELOG.md index c9ac1a301a..9aeec07ae3 100644 --- a/plugins/airbrake/CHANGELOG.md +++ b/plugins/airbrake/CHANGELOG.md @@ -1,5 +1,51 @@ # @backstage/plugin-airbrake +## 0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/dev-utils@1.0.5 + - @backstage/test-utils@1.1.3 + +## 0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/dev-utils@1.0.5-next.1 + +## 0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/dev-utils@1.0.5-next.0 + - @backstage/test-utils@1.1.3-next.0 + +## 0.3.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/test-utils@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/dev-utils@1.0.4 + ## 0.3.7-next.3 ### Patch Changes diff --git a/plugins/airbrake/api-report.md b/plugins/airbrake/api-report.md index bd274e604d..e48fbf9cde 100644 --- a/plugins/airbrake/api-report.md +++ b/plugins/airbrake/api-report.md @@ -13,6 +13,7 @@ export const airbrakePlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; diff --git a/plugins/airbrake/package.json b/plugins/airbrake/package.json index 665929d69f..6c0e69ce4d 100644 --- a/plugins/airbrake/package.json +++ b/plugins/airbrake/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-airbrake", - "version": "0.3.7-next.3", + "version": "0.3.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,13 +23,13 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/test-utils": "^1.1.2-next.2", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/test-utils": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -40,10 +40,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/app-defaults": "^1.0.4-next.3", - "@backstage/cli": "^0.18.0-next.3", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/app-defaults": "^1.0.5", + "@backstage/cli": "^0.18.1", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", @@ -51,7 +51,7 @@ "@types/node": "^16.11.26", "@types/object-hash": "^2.2.1", "cross-fetch": "^3.1.5", - "msw": "^0.44.0", + "msw": "^0.45.0", "react-router": "6.0.0-beta.0" }, "files": [ diff --git a/plugins/allure/CHANGELOG.md b/plugins/allure/CHANGELOG.md index b4e0dd916a..f93b59fbae 100644 --- a/plugins/allure/CHANGELOG.md +++ b/plugins/allure/CHANGELOG.md @@ -1,5 +1,44 @@ # @backstage/plugin-allure +## 0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.1.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.23 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.1.23-next.3 ### Patch Changes diff --git a/plugins/allure/api-report.md b/plugins/allure/api-report.md index c5c4253cd4..e6f5d2aa67 100644 --- a/plugins/allure/api-report.md +++ b/plugins/allure/api-report.md @@ -21,6 +21,7 @@ export const allurePlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; diff --git a/plugins/allure/package.json b/plugins/allure/package.json index 508f42f14c..7aed659e1d 100644 --- a/plugins/allure/package.json +++ b/plugins/allure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-allure", "description": "A Backstage plugin that integrates with Allure", - "version": "0.1.23-next.3", + "version": "0.1.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -25,11 +25,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -40,17 +40,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/analytics-module-ga/CHANGELOG.md b/plugins/analytics-module-ga/CHANGELOG.md index f24ee40ec9..10ecbc4def 100644 --- a/plugins/analytics-module-ga/CHANGELOG.md +++ b/plugins/analytics-module-ga/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-analytics-module-ga +## 0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.1.19-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.18 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + ## 0.1.18-next.3 ### Patch Changes diff --git a/plugins/analytics-module-ga/api-report.md b/plugins/analytics-module-ga/api-report.md index 9a359f81e9..557f472f71 100644 --- a/plugins/analytics-module-ga/api-report.md +++ b/plugins/analytics-module-ga/api-report.md @@ -10,7 +10,7 @@ import { Config } from '@backstage/config'; import { IdentityApi } from '@backstage/core-plugin-api'; // @public @deprecated (undocumented) -export const analyticsModuleGA: BackstagePlugin<{}, {}>; +export const analyticsModuleGA: BackstagePlugin<{}, {}, {}>; // @public export class GoogleAnalytics implements AnalyticsApi { diff --git a/plugins/analytics-module-ga/package.json b/plugins/analytics-module-ga/package.json index 499a957d70..6254c436d7 100644 --- a/plugins/analytics-module-ga/package.json +++ b/plugins/analytics-module-ga/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-analytics-module-ga", - "version": "0.1.18-next.3", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -25,9 +25,9 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -38,17 +38,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/apache-airflow/CHANGELOG.md b/plugins/apache-airflow/CHANGELOG.md index 2e3a56971c..4306582b59 100644 --- a/plugins/apache-airflow/CHANGELOG.md +++ b/plugins/apache-airflow/CHANGELOG.md @@ -1,5 +1,42 @@ # @backstage/plugin-apache-airflow +## 0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.2.0 + +### Minor Changes + +- 01f976ea72: Exposed DagTableComponent as standalone component + added a prop to get only select DAGs instead of the full list + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + ## 0.2.0-next.3 ### Patch Changes diff --git a/plugins/apache-airflow/api-report.md b/plugins/apache-airflow/api-report.md index 333e4543cf..2f03d34205 100644 --- a/plugins/apache-airflow/api-report.md +++ b/plugins/apache-airflow/api-report.md @@ -9,9 +9,7 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { RouteRef } from '@backstage/core-plugin-api'; // @public -export const ApacheAirflowDagTable: ({ - dagIds, - }: { +export const ApacheAirflowDagTable: (props: { dagIds?: string[] | undefined; }) => JSX.Element; @@ -27,6 +25,7 @@ export const apacheAirflowPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; ``` diff --git a/plugins/apache-airflow/package.json b/plugins/apache-airflow/package.json index 8494b1e7a8..1c8a532a9c 100644 --- a/plugins/apache-airflow/package.json +++ b/plugins/apache-airflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-apache-airflow", - "version": "0.2.0-next.3", + "version": "0.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,8 +23,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -36,16 +36,16 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx b/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx index 2514d70d45..fcd87b2020 100644 --- a/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx +++ b/plugins/apache-airflow/src/components/DagTableComponent/DagTableComponent.tsx @@ -134,7 +134,8 @@ type DagTableComponentProps = { dagIds?: string[]; }; -export const DagTableComponent = ({ dagIds }: DagTableComponentProps) => { +export const DagTableComponent = (props: DagTableComponentProps) => { + const { dagIds } = props; const apiClient = useApi(apacheAirflowApiRef); const { value, loading, error } = useAsync(async (): Promise => { diff --git a/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md b/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md index c6ca346a62..4e030b2264 100644 --- a/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md +++ b/plugins/api-docs-module-protoc-gen-doc/CHANGELOG.md @@ -1,5 +1,11 @@ # @backstage/plugin-api-docs-module-protoc-gen-doc +## 0.1.0 + +### Minor Changes + +- e0328f2107: Added the new `grpcDocsApiWidget` to render `protoc-gen-doc` generated descriptors by the `grpc-docs` package. + ## 0.1.0-next.0 ### Minor Changes diff --git a/plugins/api-docs-module-protoc-gen-doc/package.json b/plugins/api-docs-module-protoc-gen-doc/package.json index 00409845d0..925f81219f 100644 --- a/plugins/api-docs-module-protoc-gen-doc/package.json +++ b/plugins/api-docs-module-protoc-gen-doc/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-api-docs-module-protoc-gen-doc", "description": "Additional functionalities for the api-docs plugin that renders the output of the protoc-gen-doc", - "version": "0.1.0-next.0", + "version": "0.1.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -37,7 +37,7 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.1", + "@backstage/cli": "^0.18.1-next.0", "@testing-library/jest-dom": "^5.16.4", "@types/react": "^16.13.1 || ^17.0.0" }, diff --git a/plugins/api-docs/CHANGELOG.md b/plugins/api-docs/CHANGELOG.md index 022a606aaa..3d4dae36f1 100644 --- a/plugins/api-docs/CHANGELOG.md +++ b/plugins/api-docs/CHANGELOG.md @@ -1,5 +1,62 @@ # @backstage/plugin-api-docs +## 0.8.8 + +### Patch Changes + +- dae12c71cf: Updated dependency `@asyncapi/react-component` to `1.0.0-next.40`. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog@1.5.0 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.8.8-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/plugin-catalog@1.5.0-next.2 + +## 0.8.8-next.1 + +### Patch Changes + +- dae12c71cf: Updated dependency `@asyncapi/react-component` to `1.0.0-next.40`. +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog@1.5.0-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## 0.8.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog@1.5.0-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.8.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- b76eea25ed: Updated dependency `@asyncapi/react-component` to `1.0.0-next.39`. +- a274fe38b9: Add hidden title column to catalog and API table to enable filtering by title. +- 9432a05cf3: Set font colors correctly for descriptions containing HTML +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-catalog@1.4.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.8.7-next.3 ### Patch Changes diff --git a/plugins/api-docs/api-report.md b/plugins/api-docs/api-report.md index 991c73d4ab..0872d97355 100644 --- a/plugins/api-docs/api-report.md +++ b/plugins/api-docs/api-report.md @@ -17,13 +17,9 @@ import { TableColumn } from '@backstage/core-components'; import { TableProps } from '@backstage/core-components'; import { UserListFilterKind } from '@backstage/plugin-catalog-react'; -// Warning: (ae-missing-release-tag) "ApiDefinitionCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const ApiDefinitionCard: () => JSX.Element; -// Warning: (ae-missing-release-tag) "ApiDefinitionWidget" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type ApiDefinitionWidget = { type: string; @@ -32,14 +28,17 @@ export type ApiDefinitionWidget = { rawLanguage?: string; }; -// Warning: (ae-forgotten-export) The symbol "ApiDocsConfig" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "apiDocsConfigRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public (undocumented) +export interface ApiDocsConfig { + // (undocumented) + getApiDefinitionWidget: ( + apiEntity: ApiEntity, + ) => ApiDefinitionWidget | undefined; +} + // @public (undocumented) export const apiDocsConfigRef: ApiRef; -// Warning: (ae-missing-release-tag) "apiDocsPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) const apiDocsPlugin: BackstagePlugin< { @@ -47,7 +46,8 @@ const apiDocsPlugin: BackstagePlugin< }, { registerApi: ExternalRouteRef; - } + }, + {} >; export { apiDocsPlugin }; export { apiDocsPlugin as plugin }; @@ -57,54 +57,38 @@ export const ApiExplorerIndexPage: ( props: DefaultApiExplorerPageProps, ) => JSX.Element; -// Warning: (ae-missing-release-tag) "ApiExplorerPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const ApiExplorerPage: ( props: DefaultApiExplorerPageProps, ) => JSX.Element; -// Warning: (ae-missing-release-tag) "ApiTypeTitle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const ApiTypeTitle: ({ - apiEntity, -}: { - apiEntity: ApiEntity; -}) => JSX.Element; +export const ApiTypeTitle: (props: { apiEntity: ApiEntity }) => JSX.Element; -// Warning: (ae-missing-release-tag) "AsyncApiDefinitionWidget" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const AsyncApiDefinitionWidget: ( props: AsyncApiDefinitionWidgetProps, ) => JSX.Element; -// Warning: (ae-missing-release-tag) "AsyncApiDefinitionWidgetProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type AsyncApiDefinitionWidgetProps = { definition: string; }; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ConsumedApisCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const ConsumedApisCard: ({ variant }: Props) => JSX.Element; +export const ConsumedApisCard: (props: { + variant?: InfoCardVariants; +}) => JSX.Element; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ConsumingComponentsCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const ConsumingComponentsCard: ({ variant }: Props_4) => JSX.Element; +export const ConsumingComponentsCard: (props: { + variant?: InfoCardVariants; +}) => JSX.Element; // @public -export const DefaultApiExplorerPage: ({ - initiallySelectedFilter, - columns, - actions, -}: DefaultApiExplorerPageProps) => JSX.Element; +export const DefaultApiExplorerPage: ( + props: DefaultApiExplorerPageProps, +) => JSX.Element; // @public export type DefaultApiExplorerPageProps = { @@ -113,119 +97,80 @@ export type DefaultApiExplorerPageProps = { actions?: TableProps['actions']; }; -// Warning: (ae-missing-release-tag) "defaultDefinitionWidgets" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function defaultDefinitionWidgets(): ApiDefinitionWidget[]; -// Warning: (ae-missing-release-tag) "EntityApiDefinitionCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const EntityApiDefinitionCard: () => JSX.Element; -// Warning: (ae-missing-release-tag) "EntityConsumedApisCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityConsumedApisCard: ({ - variant, -}: { +export const EntityConsumedApisCard: (props: { variant?: InfoCardVariants | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "EntityConsumingComponentsCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityConsumingComponentsCard: ({ - variant, -}: { +export const EntityConsumingComponentsCard: (props: { variant?: InfoCardVariants | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "EntityHasApisCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityHasApisCard: ({ - variant, -}: { +export const EntityHasApisCard: (props: { variant?: InfoCardVariants | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "EntityProvidedApisCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityProvidedApisCard: ({ - variant, -}: { +export const EntityProvidedApisCard: (props: { variant?: InfoCardVariants | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "EntityProvidingComponentsCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityProvidingComponentsCard: ({ - variant, -}: { +export const EntityProvidingComponentsCard: (props: { variant?: InfoCardVariants | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "GraphQlDefinitionWidget" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const GraphQlDefinitionWidget: ( props: GraphQlDefinitionWidgetProps, ) => JSX.Element; -// Warning: (ae-missing-release-tag) "GraphQlDefinitionWidgetProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type GraphQlDefinitionWidgetProps = { definition: string; }; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "HasApisCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const HasApisCard: ({ variant }: Props_2) => JSX.Element; +export const HasApisCard: (props: { + variant?: InfoCardVariants; +}) => JSX.Element; -// Warning: (ae-missing-release-tag) "OpenApiDefinitionWidget" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const OpenApiDefinitionWidget: ( props: OpenApiDefinitionWidgetProps, ) => JSX.Element; -// Warning: (ae-missing-release-tag) "OpenApiDefinitionWidgetProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type OpenApiDefinitionWidgetProps = { definition: string; }; -// Warning: (ae-missing-release-tag) "PlainApiDefinitionWidget" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const PlainApiDefinitionWidget: ( props: PlainApiDefinitionWidgetProps, ) => JSX.Element; -// Warning: (ae-missing-release-tag) "PlainApiDefinitionWidgetProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type PlainApiDefinitionWidgetProps = { definition: any; language: string; }; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ProvidedApisCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const ProvidedApisCard: ({ variant }: Props_3) => JSX.Element; +export const ProvidedApisCard: (props: { + variant?: InfoCardVariants; +}) => JSX.Element; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ProvidingComponentsCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const ProvidingComponentsCard: ({ variant }: Props_5) => JSX.Element; +export const ProvidingComponentsCard: (props: { + variant?: InfoCardVariants; +}) => JSX.Element; ``` diff --git a/plugins/api-docs/package.json b/plugins/api-docs/package.json index 96b95b51f0..75d2802de3 100644 --- a/plugins/api-docs/package.json +++ b/plugins/api-docs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-api-docs", "description": "A Backstage plugin that helps represent API entities in the frontend", - "version": "0.8.7-next.3", + "version": "0.8.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,13 +33,13 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@asyncapi/react-component": "1.0.0-next.39", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog": "^1.4.0-next.3", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@asyncapi/react-component": "1.0.0-next.40", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog": "^1.5.0", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -57,10 +57,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", @@ -68,7 +68,7 @@ "@types/node": "^16.11.26", "@types/swagger-ui-react": "^4.1.1", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.tsx b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.tsx index 353b973626..679069f209 100644 --- a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.tsx +++ b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionCard.tsx @@ -24,6 +24,7 @@ import { PlainApiDefinitionWidget } from '../PlainApiDefinitionWidget'; import { CardTab, TabbedCard } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; +/** @public */ export const ApiDefinitionCard = () => { const { entity } = useEntity(); const config = useApi(apiDocsConfigRef); diff --git a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx index 3b7aa406d4..03a56eaa78 100644 --- a/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/ApiDefinitionCard/ApiDefinitionWidget.tsx @@ -19,6 +19,7 @@ import { GraphQlDefinitionWidget } from '../GraphQlDefinitionWidget'; import { OpenApiDefinitionWidget } from '../OpenApiDefinitionWidget'; import { GrpcApiDefinitionWidget } from '../GrpcApiDefinitionWidget'; +/** @public */ export type ApiDefinitionWidget = { type: string; title: string; @@ -26,6 +27,7 @@ export type ApiDefinitionWidget = { rawLanguage?: string; }; +/** @public */ export function defaultDefinitionWidgets(): ApiDefinitionWidget[] { return [ { diff --git a/plugins/api-docs/src/components/ApiDefinitionCard/ApiTypeTitle.tsx b/plugins/api-docs/src/components/ApiDefinitionCard/ApiTypeTitle.tsx index 787c91f12b..93ab7cc05a 100644 --- a/plugins/api-docs/src/components/ApiDefinitionCard/ApiTypeTitle.tsx +++ b/plugins/api-docs/src/components/ApiDefinitionCard/ApiTypeTitle.tsx @@ -19,7 +19,11 @@ import React from 'react'; import { apiDocsConfigRef } from '../../config'; import { useApi } from '@backstage/core-plugin-api'; -export const ApiTypeTitle = ({ apiEntity }: { apiEntity: ApiEntity }) => { +/** + * @public + */ +export const ApiTypeTitle = (props: { apiEntity: ApiEntity }) => { + const { apiEntity } = props; const config = useApi(apiDocsConfigRef); const definition = config.getApiDefinitionWidget(apiEntity); const type = definition ? definition.title : apiEntity.spec.type; diff --git a/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.tsx b/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.tsx index b0acd3567c..ad43205c5f 100644 --- a/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.tsx +++ b/plugins/api-docs/src/components/ApiExplorerPage/DefaultApiExplorerPage.tsx @@ -64,11 +64,9 @@ export type DefaultApiExplorerPageProps = { * DefaultApiExplorerPage * @public */ -export const DefaultApiExplorerPage = ({ - initiallySelectedFilter = 'all', - columns, - actions, -}: DefaultApiExplorerPageProps) => { +export const DefaultApiExplorerPage = (props: DefaultApiExplorerPageProps) => { + const { initiallySelectedFilter = 'all', columns, actions } = props; + const configApi = useApi(configApiRef); const generatedSubtitle = `${ configApi.getOptionalString('organization.name') ?? 'Backstage' diff --git a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.tsx b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.tsx index fde41425c9..588e62ceb7 100644 --- a/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.tsx +++ b/plugins/api-docs/src/components/ApisCards/ConsumedApisCard.tsx @@ -32,11 +32,11 @@ import { WarningPanel, } from '@backstage/core-components'; -type Props = { - variant?: InfoCardVariants; -}; - -export const ConsumedApisCard = ({ variant = 'gridItem' }: Props) => { +/** + * @public + */ +export const ConsumedApisCard = (props: { variant?: InfoCardVariants }) => { + const { variant = 'gridItem' } = props; const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { type: RELATION_CONSUMES_API, diff --git a/plugins/api-docs/src/components/ApisCards/HasApisCard.tsx b/plugins/api-docs/src/components/ApisCards/HasApisCard.tsx index bb22f82269..b09cafacda 100644 --- a/plugins/api-docs/src/components/ApisCards/HasApisCard.tsx +++ b/plugins/api-docs/src/components/ApisCards/HasApisCard.tsx @@ -33,10 +33,6 @@ import { WarningPanel, } from '@backstage/core-components'; -type Props = { - variant?: InfoCardVariants; -}; - const columns: TableColumn[] = [ EntityTable.columns.createEntityRefColumn({ defaultKind: 'API' }), EntityTable.columns.createOwnerColumn(), @@ -45,7 +41,11 @@ const columns: TableColumn[] = [ EntityTable.columns.createMetadataDescriptionColumn(), ]; -export const HasApisCard = ({ variant = 'gridItem' }: Props) => { +/** + * @public + */ +export const HasApisCard = (props: { variant?: InfoCardVariants }) => { + const { variant = 'gridItem' } = props; const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { type: RELATION_HAS_PART, diff --git a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.tsx b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.tsx index 6ffb6365d2..e9c63d9956 100644 --- a/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.tsx +++ b/plugins/api-docs/src/components/ApisCards/ProvidedApisCard.tsx @@ -32,11 +32,11 @@ import { WarningPanel, } from '@backstage/core-components'; -type Props = { - variant?: InfoCardVariants; -}; - -export const ProvidedApisCard = ({ variant = 'gridItem' }: Props) => { +/** + * @public + */ +export const ProvidedApisCard = (props: { variant?: InfoCardVariants }) => { + const { variant = 'gridItem' } = props; const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { type: RELATION_PROVIDES_API, diff --git a/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx b/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx index 03bc6fa8a6..2e8710b008 100644 --- a/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/AsyncApiDefinitionWidget/AsyncApiDefinitionWidget.tsx @@ -25,10 +25,12 @@ const LazyAsyncApiDefinition = React.lazy(() => })), ); +/** @public */ export type AsyncApiDefinitionWidgetProps = { definition: string; }; +/** @public */ export const AsyncApiDefinitionWidget = ( props: AsyncApiDefinitionWidgetProps, ) => { diff --git a/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.tsx b/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.tsx index af3dcb7204..aa6afc7822 100644 --- a/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.tsx +++ b/plugins/api-docs/src/components/ComponentsCards/ConsumingComponentsCard.tsx @@ -34,11 +34,13 @@ import { WarningPanel, } from '@backstage/core-components'; -type Props = { +/** + * @public + */ +export const ConsumingComponentsCard = (props: { variant?: InfoCardVariants; -}; - -export const ConsumingComponentsCard = ({ variant = 'gridItem' }: Props) => { +}) => { + const { variant = 'gridItem' } = props; const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { type: RELATION_API_CONSUMED_BY, diff --git a/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.tsx b/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.tsx index 0be746de6d..435021e008 100644 --- a/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.tsx +++ b/plugins/api-docs/src/components/ComponentsCards/ProvidingComponentsCard.tsx @@ -34,11 +34,11 @@ import { WarningPanel, } from '@backstage/core-components'; -type Props = { +/** @public */ +export const ProvidingComponentsCard = (props: { variant?: InfoCardVariants; -}; - -export const ProvidingComponentsCard = ({ variant = 'gridItem' }: Props) => { +}) => { + const { variant = 'gridItem' } = props; const { entity } = useEntity(); const { entities, loading, error } = useRelatedEntities(entity, { type: RELATION_API_PROVIDED_BY, diff --git a/plugins/api-docs/src/components/GraphQlDefinitionWidget/GraphQlDefinitionWidget.tsx b/plugins/api-docs/src/components/GraphQlDefinitionWidget/GraphQlDefinitionWidget.tsx index 1f8a796249..b5cf06e828 100644 --- a/plugins/api-docs/src/components/GraphQlDefinitionWidget/GraphQlDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/GraphQlDefinitionWidget/GraphQlDefinitionWidget.tsx @@ -25,10 +25,12 @@ const LazyGraphQlDefinition = React.lazy(() => })), ); +/** @public */ export type GraphQlDefinitionWidgetProps = { definition: string; }; +/** @public */ export const GraphQlDefinitionWidget = ( props: GraphQlDefinitionWidgetProps, ) => { diff --git a/plugins/api-docs/src/components/GrpcApiDefinitionWidget/GrpcApiDefinitionWidget.tsx b/plugins/api-docs/src/components/GrpcApiDefinitionWidget/GrpcApiDefinitionWidget.tsx index c5f9b071ef..b6bf317099 100644 --- a/plugins/api-docs/src/components/GrpcApiDefinitionWidget/GrpcApiDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/GrpcApiDefinitionWidget/GrpcApiDefinitionWidget.tsx @@ -19,10 +19,12 @@ import { CodeSnippet } from '@backstage/core-components'; import { useTheme } from '@material-ui/core/styles'; import { BackstageTheme } from '@backstage/theme'; +/** @public */ export type GrpcApiDefinitionWidgetProps = { definition: string; }; +/** @public */ export const GrpcApiDefinitionWidget = ( props: GrpcApiDefinitionWidgetProps, ) => { diff --git a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx index 606e476454..424a52136b 100644 --- a/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/OpenApiDefinitionWidget/OpenApiDefinitionWidget.tsx @@ -25,10 +25,12 @@ const LazyOpenApiDefinition = React.lazy(() => })), ); +/** @public */ export type OpenApiDefinitionWidgetProps = { definition: string; }; +/** @public */ export const OpenApiDefinitionWidget = ( props: OpenApiDefinitionWidgetProps, ) => { diff --git a/plugins/api-docs/src/components/PlainApiDefinitionWidget/PlainApiDefinitionWidget.tsx b/plugins/api-docs/src/components/PlainApiDefinitionWidget/PlainApiDefinitionWidget.tsx index b7f1e8afc0..c7d7d83c8d 100644 --- a/plugins/api-docs/src/components/PlainApiDefinitionWidget/PlainApiDefinitionWidget.tsx +++ b/plugins/api-docs/src/components/PlainApiDefinitionWidget/PlainApiDefinitionWidget.tsx @@ -17,11 +17,13 @@ import React from 'react'; import { CodeSnippet } from '@backstage/core-components'; +/** @public */ export type PlainApiDefinitionWidgetProps = { definition: any; language: string; }; +/** @public */ export const PlainApiDefinitionWidget = ( props: PlainApiDefinitionWidgetProps, ) => { diff --git a/plugins/api-docs/src/config.ts b/plugins/api-docs/src/config.ts index 979340164b..4d1e650720 100644 --- a/plugins/api-docs/src/config.ts +++ b/plugins/api-docs/src/config.ts @@ -18,10 +18,12 @@ import { ApiEntity } from '@backstage/catalog-model'; import { ApiDefinitionWidget } from './components/ApiDefinitionCard/ApiDefinitionWidget'; import { createApiRef } from '@backstage/core-plugin-api'; +/** @public */ export const apiDocsConfigRef = createApiRef({ id: 'plugin.api-docs.config', }); +/** @public */ export interface ApiDocsConfig { getApiDefinitionWidget: ( apiEntity: ApiEntity, diff --git a/plugins/api-docs/src/index.ts b/plugins/api-docs/src/index.ts index fe98e9c70e..49b2805aad 100644 --- a/plugins/api-docs/src/index.ts +++ b/plugins/api-docs/src/index.ts @@ -21,6 +21,7 @@ */ export * from './components'; +export type { ApiDocsConfig } from './config'; export { apiDocsConfigRef } from './config'; export { apiDocsPlugin, diff --git a/plugins/api-docs/src/plugin.ts b/plugins/api-docs/src/plugin.ts index f1928f4443..cabe2d82cd 100644 --- a/plugins/api-docs/src/plugin.ts +++ b/plugins/api-docs/src/plugin.ts @@ -25,6 +25,7 @@ import { createRoutableExtension, } from '@backstage/core-plugin-api'; +/** @public */ export const apiDocsPlugin = createPlugin({ id: 'api-docs', routes: { @@ -49,6 +50,7 @@ export const apiDocsPlugin = createPlugin({ }, }); +/** @public */ export const ApiExplorerPage = apiDocsPlugin.provide( createRoutableExtension({ name: 'ApiExplorerPage', @@ -58,6 +60,7 @@ export const ApiExplorerPage = apiDocsPlugin.provide( }), ); +/** @public */ export const EntityApiDefinitionCard = apiDocsPlugin.provide( createComponentExtension({ name: 'EntityApiDefinitionCard', @@ -68,6 +71,7 @@ export const EntityApiDefinitionCard = apiDocsPlugin.provide( }), ); +/** @public */ export const EntityConsumedApisCard = apiDocsPlugin.provide( createComponentExtension({ name: 'EntityConsumedApisCard', @@ -78,6 +82,7 @@ export const EntityConsumedApisCard = apiDocsPlugin.provide( }), ); +/** @public */ export const EntityConsumingComponentsCard = apiDocsPlugin.provide( createComponentExtension({ name: 'EntityConsumingComponentsCard', @@ -90,6 +95,7 @@ export const EntityConsumingComponentsCard = apiDocsPlugin.provide( }), ); +/** @public */ export const EntityProvidedApisCard = apiDocsPlugin.provide( createComponentExtension({ name: 'EntityProvidedApisCard', @@ -100,6 +106,7 @@ export const EntityProvidedApisCard = apiDocsPlugin.provide( }), ); +/** @public */ export const EntityProvidingComponentsCard = apiDocsPlugin.provide( createComponentExtension({ name: 'EntityProvidingComponentsCard', @@ -112,6 +119,7 @@ export const EntityProvidingComponentsCard = apiDocsPlugin.provide( }), ); +/** @public */ export const EntityHasApisCard = apiDocsPlugin.provide( createComponentExtension({ name: 'EntityHasApisCard', diff --git a/plugins/apollo-explorer/.eslintrc.js b/plugins/apollo-explorer/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/apollo-explorer/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/apollo-explorer/CHANGELOG.md b/plugins/apollo-explorer/CHANGELOG.md new file mode 100644 index 0000000000..fbe32ec2db --- /dev/null +++ b/plugins/apollo-explorer/CHANGELOG.md @@ -0,0 +1,37 @@ +# @backstage/plugin-apollo-explorer + +## 0.1.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.1.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.0 + +### Minor Changes + +- d8fec19542: Apollo Explorer plugin now available! Installation instructions can be found in the plugin README + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 diff --git a/plugins/apollo-explorer/README.md b/plugins/apollo-explorer/README.md new file mode 100644 index 0000000000..98f3116966 --- /dev/null +++ b/plugins/apollo-explorer/README.md @@ -0,0 +1,66 @@ +# apollo-explorer + +Welcome to the Apollo Explorer plugin! + +This plugin allows users to directly embed an [Apollo](https://www.apollographql.com) graph explorer directly into +Backstage! + +## Getting started + +### Getting an Apollo Graph Reference + +First things first, you will need an Apollo account, and a graph imported into your account. This is beyond the scope of +this plugin, so if you are totally new to Apollo, please reference their official +documentation [here](https://www.apollographql.com/docs). + +Once you have a graph set up in Apollo, we need to grab the graph reference. First, go to your Apollo graphs home page and choose the graph you wish to embed. + +![Apollo Graph List](./docs/img/apollo-graph-list.png) + +Once you are in your graph explorer, click the dropdown next to the share icon and select `Share as Embedded` + +![Share as Embedded](./docs/img/share-as-embedded.png) + +This modal contains a number of useful properties, all of which can be passed to the plugin via the component properties, but the only mandatory input we need from here is the `graphRef`. + +![Graph Ref](./docs/img/graph-ref.png) + +Hold on to this snippet for a second while we set up the plugin ✨ + +### Installing the Backstage Plugin + +First, add the plugin to your Backstage app + +```shell +yarn --cwd packages/app add @backstage/plugin-apollo-explorer +``` + +Then, in `packages/app/src/App.tsx` add the plugin as a `Route` + +```typescript + + } +/> +``` + +Then, in `packages/app/src/components/Root/Root.tsx` add a sidebar item so users can find your beautiful plugin! + +```typescript + +``` + +That's it! You should now see an `Apollo Explorer` item in your sidebar, and if you click it, you should see your graph(s) load and direct you to authenticate via Apollo! + +![Needs Auth](./docs/img/needs-auth.png) + +Once you authenticate, your graph is ready to use 🚀 + +![Logged In](./docs/img/logged-in.png) diff --git a/plugins/apollo-explorer/api-report.md b/plugins/apollo-explorer/api-report.md new file mode 100644 index 0000000000..1d3b41eac1 --- /dev/null +++ b/plugins/apollo-explorer/api-report.md @@ -0,0 +1,45 @@ +## API Report File for "@backstage/plugin-apollo-explorer" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { JSONObject } from '@apollo/explorer/src/helpers/types'; +import { RouteRef } from '@backstage/core-plugin-api'; + +// @public +export const ApolloExplorerPage: (props: { + title?: string | undefined; + subtitle?: string | undefined; + endpoints: { + title: string; + graphRef: string; + persistExplorerState?: boolean | undefined; + initialState?: + | { + document?: string | undefined; + variables?: JSONObject | undefined; + headers?: Record | undefined; + displayOptions: { + docsPanelState?: 'closed' | 'open' | undefined; + showHeadersAndEnvVars?: boolean | undefined; + theme?: 'dark' | 'light' | undefined; + }; + } + | undefined; + }[]; +}) => JSX.Element; + +// @public +export const apolloExplorerPlugin: BackstagePlugin< + { + root: RouteRef; + }, + {}, + {} +>; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/apollo-explorer/dev/index.tsx b/plugins/apollo-explorer/dev/index.tsx new file mode 100644 index 0000000000..df61267811 --- /dev/null +++ b/plugins/apollo-explorer/dev/index.tsx @@ -0,0 +1,27 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { createDevApp } from '@backstage/dev-utils'; +import { apolloExplorerPlugin, ApolloExplorerPage } from '../src/plugin'; + +createDevApp() + .registerPlugin(apolloExplorerPlugin) + .addPage({ + element: , + title: 'Root Page', + path: '/apollo-explorer', + }) + .render(); diff --git a/plugins/apollo-explorer/docs/img/apollo-graph-list.png b/plugins/apollo-explorer/docs/img/apollo-graph-list.png new file mode 100644 index 0000000000..53a1c517aa Binary files /dev/null and b/plugins/apollo-explorer/docs/img/apollo-graph-list.png differ diff --git a/plugins/apollo-explorer/docs/img/graph-ref.png b/plugins/apollo-explorer/docs/img/graph-ref.png new file mode 100644 index 0000000000..062ebe50b7 Binary files /dev/null and b/plugins/apollo-explorer/docs/img/graph-ref.png differ diff --git a/plugins/apollo-explorer/docs/img/logged-in.png b/plugins/apollo-explorer/docs/img/logged-in.png new file mode 100644 index 0000000000..5c5c81347d Binary files /dev/null and b/plugins/apollo-explorer/docs/img/logged-in.png differ diff --git a/plugins/apollo-explorer/docs/img/needs-auth.png b/plugins/apollo-explorer/docs/img/needs-auth.png new file mode 100644 index 0000000000..03c6a9c5fc Binary files /dev/null and b/plugins/apollo-explorer/docs/img/needs-auth.png differ diff --git a/plugins/apollo-explorer/docs/img/share-as-embedded.png b/plugins/apollo-explorer/docs/img/share-as-embedded.png new file mode 100644 index 0000000000..672ed5d8ef Binary files /dev/null and b/plugins/apollo-explorer/docs/img/share-as-embedded.png differ diff --git a/plugins/apollo-explorer/package.json b/plugins/apollo-explorer/package.json new file mode 100644 index 0000000000..b860e61900 --- /dev/null +++ b/plugins/apollo-explorer/package.json @@ -0,0 +1,54 @@ +{ + "name": "@backstage/plugin-apollo-explorer", + "version": "0.1.1", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "frontend-plugin" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/theme": "^0.2.16", + "@material-ui/core": "^4.9.13", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.57", + "react-use": "^17.2.4", + "@apollo/explorer": "^1.1.1", + "use-deep-compare-effect": "^1.8.1" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "@types/jest": "*", + "@types/node": "*", + "msw": "^0.45.0", + "cross-fetch": "^3.1.5" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx new file mode 100644 index 0000000000..bce3ce00bb --- /dev/null +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/ApolloExplorerBrowser.tsx @@ -0,0 +1,85 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React, { useState } from 'react'; +import { Divider, makeStyles, Tab, Tabs } from '@material-ui/core'; +import { BackstageTheme } from '@backstage/theme'; +import { JSONObject } from '@apollo/explorer/src/helpers/types'; +import { ApolloExplorer } from '@apollo/explorer/react'; +import { Content } from '@backstage/core-components'; + +const useStyles = makeStyles(theme => ({ + tabs: { + background: theme.palette.background.paper, + }, + root: { + height: '100%', + }, + content: { + height: '100%', + }, + explorer: { + height: '95%', + }, +})); + +export type ApolloEndpointProps = { + title: string; + graphRef: string; + persistExplorerState?: boolean; + initialState?: { + document?: string; + variables?: JSONObject; + headers?: Record; + displayOptions: { + docsPanelState?: 'open' | 'closed'; + showHeadersAndEnvVars?: boolean; + theme?: 'dark' | 'light'; + }; + }; +}; + +type Props = { + endpoints: ApolloEndpointProps[]; +}; + +export const ApolloExplorerBrowser = ({ endpoints }: Props) => { + const classes = useStyles(); + const [tabIndex, setTabIndex] = useState(0); + + return ( +
+ setTabIndex(value)} + indicatorColor="primary" + > + {endpoints.map(({ title }, index) => ( + + ))} + + + + + +
+ ); +}; diff --git a/plugins/scaffolder/src/next/TemplateWizardPage/SecretsContext/index.ts b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/index.ts similarity index 85% rename from plugins/scaffolder/src/next/TemplateWizardPage/SecretsContext/index.ts rename to plugins/apollo-explorer/src/components/ApolloExplorerBrowser/index.ts index 65b530dea1..d8bc44bfa7 100644 --- a/plugins/scaffolder/src/next/TemplateWizardPage/SecretsContext/index.ts +++ b/plugins/apollo-explorer/src/components/ApolloExplorerBrowser/index.ts @@ -13,8 +13,4 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -export { - useTemplateSecrets, - SecretsContext, - SecretsContextProvider, -} from './SecretsContext'; +export { ApolloExplorerBrowser } from './ApolloExplorerBrowser'; diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx new file mode 100644 index 0000000000..f90af9bc17 --- /dev/null +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/ApolloExplorerPage.tsx @@ -0,0 +1,54 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import { Content, Header, Page } from '@backstage/core-components'; +import { ApolloExplorerBrowser } from '../ApolloExplorerBrowser'; +import { JSONObject } from '@apollo/explorer/src/helpers/types'; + +type EndpointProps = { + title: string; + graphRef: string; + persistExplorerState?: boolean; + initialState?: { + document?: string; + variables?: JSONObject; + headers?: Record; + displayOptions: { + docsPanelState?: 'open' | 'closed'; + showHeadersAndEnvVars?: boolean; + theme?: 'dark' | 'light'; + }; + }; +}; + +type Props = { + title?: string | undefined; + subtitle?: string | undefined; + endpoints: EndpointProps[]; +}; + +export const ApolloExplorerPage = (props: Props) => { + const { title, subtitle, endpoints } = props; + return ( + +
+ + + + + ); +}; diff --git a/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts b/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts new file mode 100644 index 0000000000..8f62872fe6 --- /dev/null +++ b/plugins/apollo-explorer/src/components/ApolloExplorerPage/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { ApolloExplorerPage } from './ApolloExplorerPage'; diff --git a/plugins/apollo-explorer/src/index.ts b/plugins/apollo-explorer/src/index.ts new file mode 100644 index 0000000000..6d07535fc3 --- /dev/null +++ b/plugins/apollo-explorer/src/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { apolloExplorerPlugin, ApolloExplorerPage } from './plugin'; diff --git a/plugins/apollo-explorer/src/plugin.test.ts b/plugins/apollo-explorer/src/plugin.test.ts new file mode 100644 index 0000000000..0b5e41fe6e --- /dev/null +++ b/plugins/apollo-explorer/src/plugin.test.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { apolloExplorerPlugin } from './plugin'; + +describe('apollo-explorer', () => { + it('should export plugin', () => { + expect(apolloExplorerPlugin).toBeDefined(); + }); +}); diff --git a/plugins/apollo-explorer/src/plugin.ts b/plugins/apollo-explorer/src/plugin.ts new file mode 100644 index 0000000000..6f7321689b --- /dev/null +++ b/plugins/apollo-explorer/src/plugin.ts @@ -0,0 +1,45 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + createPlugin, + createRoutableExtension, +} from '@backstage/core-plugin-api'; + +import { rootRouteRef } from './routes'; + +/** + * Plugin that allows Apollo Explorer instances to be directly embedded into Backstage + * @public + */ +export const apolloExplorerPlugin = createPlugin({ + id: 'apollo-explorer', + routes: { + root: rootRouteRef, + }, +}); + +/** + * Main component that wraps the embedded graph(s) + * @public + */ +export const ApolloExplorerPage = apolloExplorerPlugin.provide( + createRoutableExtension({ + name: 'ApolloExplorerPage', + component: () => + import('./components/ApolloExplorerPage').then(m => m.ApolloExplorerPage), + mountPoint: rootRouteRef, + }), +); diff --git a/plugins/apollo-explorer/src/routes.ts b/plugins/apollo-explorer/src/routes.ts new file mode 100644 index 0000000000..c8e6a3eb9a --- /dev/null +++ b/plugins/apollo-explorer/src/routes.ts @@ -0,0 +1,20 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { createRouteRef } from '@backstage/core-plugin-api'; + +export const rootRouteRef = createRouteRef({ + id: 'apollo-explorer', +}); diff --git a/plugins/apollo-explorer/src/setupTests.ts b/plugins/apollo-explorer/src/setupTests.ts new file mode 100644 index 0000000000..9bb3e72355 --- /dev/null +++ b/plugins/apollo-explorer/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import '@testing-library/jest-dom'; +import 'cross-fetch/polyfill'; diff --git a/plugins/app-backend/CHANGELOG.md b/plugins/app-backend/CHANGELOG.md index cea1375cee..33845eb9c7 100644 --- a/plugins/app-backend/CHANGELOG.md +++ b/plugins/app-backend/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-app-backend +## 0.3.35 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## 0.3.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## 0.3.34 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/config-loader@1.1.3 + ## 0.3.34-next.3 ### Patch Changes diff --git a/plugins/app-backend/package.json b/plugins/app-backend/package.json index daacabe5f6..7ad2b50c52 100644 --- a/plugins/app-backend/package.json +++ b/plugins/app-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-app-backend", "description": "A Backstage backend plugin that serves the Backstage frontend app", - "version": "0.3.34-next.3", + "version": "0.3.35", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,8 +33,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/config-loader": "^1.1.3-next.1", + "@backstage/backend-common": "^0.15.0", + "@backstage/config-loader": "^1.1.3", "@backstage/config": "^1.0.1", "@backstage/types": "^1.0.0", "@types/express": "^4.17.6", @@ -50,12 +50,12 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "@backstage/types": "^1.0.0", "@types/supertest": "^2.0.8", "mock-fs": "^5.1.0", - "msw": "^0.44.0", + "msw": "^0.45.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts b/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts index 95de905e7a..3d0973e18c 100644 --- a/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts +++ b/plugins/app-backend/src/lib/assets/StaticAssetsStore.test.ts @@ -14,12 +14,25 @@ * limitations under the License. */ +import { Knex as KnexType } from 'knex'; import { getVoidLogger } from '@backstage/backend-common'; import { TestDatabases } from '@backstage/backend-test-utils'; import { StaticAssetsStore } from './StaticAssetsStore'; const logger = getVoidLogger(); +function createDatabaseManager( + client: KnexType, + skipMigrations: boolean = false, +) { + return { + getClient: async () => client, + migrations: { + skip: skipMigrations, + }, + }; +} + describe('StaticAssetsStore', () => { const databases = TestDatabases.create({ ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], @@ -28,9 +41,11 @@ describe('StaticAssetsStore', () => { it.each(databases.eachSupportedId())( 'should store and retrieve assets, %p', async databaseId => { + const client = await databases.init(databaseId); + const database = createDatabaseManager(client); const store = await StaticAssetsStore.create({ logger, - database: await databases.init(databaseId), + database, }); await store.storeAssets([ @@ -69,9 +84,11 @@ describe('StaticAssetsStore', () => { it.each(databases.eachSupportedId())( 'should update assets timestamps, but not contents, %p', async databaseId => { + const client = await databases.init(databaseId); + const database = createDatabaseManager(client); const store = await StaticAssetsStore.create({ logger, - database: await databases.init(databaseId), + database, }); await store.storeAssets([ @@ -119,7 +136,8 @@ describe('StaticAssetsStore', () => { it.each(databases.eachSupportedId())( 'should trim old assets, %p', async databaseId => { - const database = await databases.init(databaseId); + const knex = await databases.init(databaseId); + const database = createDatabaseManager(knex); const store = await StaticAssetsStore.create({ logger, database, @@ -137,12 +155,12 @@ describe('StaticAssetsStore', () => { ]); // Rewrite modified time of "old" to be 1h in the past - const updated = await database('static_assets_cache') + const updated = await knex('static_assets_cache') .where({ path: 'old' }) .update({ - last_modified_at: database.client.config.client.includes('sqlite3') - ? database.raw(`datetime('now', '-3600 seconds')`) - : database.raw(`now() + interval '-3600 seconds'`), + last_modified_at: knex.client.config.client.includes('sqlite3') + ? knex.raw(`datetime('now', '-3600 seconds')`) + : knex.raw(`now() + interval '-3600 seconds'`), }); expect(updated).toBe(1); diff --git a/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts b/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts index 70d664307e..6905d63779 100644 --- a/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts +++ b/plugins/app-backend/src/lib/assets/StaticAssetsStore.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { resolvePackagePath } from '@backstage/backend-common'; +import { + PluginDatabaseManager, + resolvePackagePath, +} from '@backstage/backend-common'; import { Knex } from 'knex'; import { Logger } from 'winston'; import { DateTime } from 'luxon'; @@ -34,7 +37,7 @@ interface StaticAssetRow { /** @internal */ export interface StaticAssetsStoreOptions { - database: Knex; + database: PluginDatabaseManager; logger: Logger; } @@ -48,15 +51,21 @@ export class StaticAssetsStore implements StaticAssetProvider { #logger: Logger; static async create(options: StaticAssetsStoreOptions) { - await options.database.migrate.latest({ - directory: migrationsDir, - }); - return new StaticAssetsStore(options); + const { database } = options; + const client = await database.getClient(); + + if (!database.migrations?.skip) { + await client.migrate.latest({ + directory: migrationsDir, + }); + } + + return new StaticAssetsStore(client, options.logger); } - private constructor(options: StaticAssetsStoreOptions) { - this.#db = options.database; - this.#logger = options.logger; + private constructor(client: Knex, logger: Logger) { + this.#db = client; + this.#logger = logger; } /** diff --git a/plugins/app-backend/src/service/router.ts b/plugins/app-backend/src/service/router.ts index b666f323db..46ecd470da 100644 --- a/plugins/app-backend/src/service/router.ts +++ b/plugins/app-backend/src/service/router.ts @@ -130,7 +130,7 @@ export async function createRouter( if (options.database) { const store = await StaticAssetsStore.create({ logger, - database: await options.database.getClient(), + database: options.database, }); const assets = await findStaticAssets(staticDir); diff --git a/plugins/auth-backend/CHANGELOG.md b/plugins/auth-backend/CHANGELOG.md index a8b47b5566..43460df12f 100644 --- a/plugins/auth-backend/CHANGELOG.md +++ b/plugins/auth-backend/CHANGELOG.md @@ -1,5 +1,61 @@ # @backstage/plugin-auth-backend +## 0.15.1 + +### Patch Changes + +- c676a9e07b: Fixed a bug in auth plugin on the backend where it ignores the skip migration database options when using the database provider. +- 2d7d6028e1: Updated dependency `@google-cloud/firestore` to `^6.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-auth-node@0.2.4 + +## 0.15.1-next.1 + +### Patch Changes + +- 2d7d6028e1: Updated dependency `@google-cloud/firestore` to `^6.0.0`. + +## 0.15.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 + +## 0.15.0 + +### Minor Changes + +- 9d4040777e: **BREAKING**: Removed all directly exported auth provider factories, option types, and sign-in resolvers. For example: `AwsAlbProviderOptions`, `bitbucketUserIdSignInResolver`, `createGithubProvider`. These are all still accessible via the `providers` export. For example, use `providers.github.create()` rather than `createGithubProvider()`, and `providers.bitbucket.resolvers.userIdMatchingUserEntityAnnotation()` rather than `bitbucketUserIdSignInResolver`. + + **BREAKING**: Removed the exported `AuthProviderFactoryOptions` type as well as the deprecated option fields of the `AuthProviderFactory` callback. This includes the `tokenManager`, `tokenIssuer`, `discovery`, and `catalogApi` fields. Existing usage of these should be replaced with the new utilities in the `resolverContext` field. The deprecated `TokenIssuer` type is now also removed, since it is no longer used. + + **BREAKING**: Removed `getEntityClaims`, use `getDefaultOwnershipEntityRefs` instead. + + **DEPRECATION**: Deprecated `AtlassianAuthProvider` as it was unintentionally exported. + +- fe8e025af5: Allowed post method on /refresh path + +### Patch Changes + +- 3cedfd8365: add Cloudflare Access auth provider to auth-backend +- f2cf79d62e: Added an option for the auth backend router to select the algorithm for the JWT token signing keys +- 8e03db907a: Auth provider now also export createAuthProviderIntegration +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- 859346bfbb: Updated dependency `google-auth-library` to `^8.0.0`. +- 3a014730dc: Add new config option for okta auth server and IDP +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/errors@1.1.0 + ## 0.15.0-next.3 ### Minor Changes diff --git a/plugins/auth-backend/api-report.md b/plugins/auth-backend/api-report.md index 8c9ec14c9e..649a31c963 100644 --- a/plugins/auth-backend/api-report.md +++ b/plugins/auth-backend/api-report.md @@ -7,6 +7,7 @@ import { BackstageIdentityResponse } from '@backstage/plugin-auth-node'; import { BackstageSignInResult } from '@backstage/plugin-auth-node'; +import { CacheClient } from '@backstage/backend-common'; import { CatalogApi } from '@backstage/catalog-client'; import { Config } from '@backstage/config'; import { Entity } from '@backstage/catalog-model'; @@ -170,6 +171,41 @@ export class CatalogIdentityClient { resolveCatalogMembership(query: MemberClaimQuery): Promise; } +// @public +export type CloudflareAccessClaims = { + aud: string[]; + email: string; + exp: number; + iat: number; + nonce: string; + identity_nonce: string; + sub: string; + iss: string; + custom: string; +}; + +// @public +export type CloudflareAccessGroup = { + id: string; + name: string; + email: string; +}; + +// @public +export type CloudflareAccessIdentityProfile = { + id: string; + name: string; + email: string; + groups: CloudflareAccessGroup[]; +}; + +// @public (undocumented) +export type CloudflareAccessResult = { + claims: CloudflareAccessClaims; + cfIdentity: CloudflareAccessIdentityProfile; + expiresInSeconds?: number; +}; + // @public export type CookieConfigurer = (ctx: { providerId: string; @@ -472,6 +508,18 @@ export const providers: Readonly<{ userIdMatchingUserEntityAnnotation(): SignInResolver; }>; }>; + cfAccess: Readonly<{ + create: (options: { + authHandler?: AuthHandler | undefined; + signIn: { + resolver: SignInResolver; + }; + cache?: CacheClient | undefined; + }) => AuthProviderFactory; + resolvers: Readonly<{ + emailMatchingUserEntityProfileEmail: () => SignInResolver; + }>; + }>; gcpIap: Readonly<{ create: (options: { authHandler?: AuthHandler | undefined; diff --git a/plugins/auth-backend/config.d.ts b/plugins/auth-backend/config.d.ts index af5a3c24be..5aff9df90a 100644 --- a/plugins/auth-backend/config.d.ts +++ b/plugins/auth-backend/config.d.ts @@ -116,6 +116,9 @@ export interface Config { issuer?: string; region: string; }; + cfaccess?: { + teamName: string; + }; }; }; } diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 5f83bbef6a..3c4b8c3a99 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-auth-backend", "description": "A Backstage backend plugin that handles authentication", - "version": "0.15.0-next.3", + "version": "0.15.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,15 +33,15 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/plugin-auth-node": "^0.2.3-next.2", - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/plugin-auth-node": "^0.2.4", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", + "@backstage/errors": "^1.1.0", "@backstage/types": "^1.0.0", "@davidzemon/passport-okta-oauth": "^0.0.5", - "@google-cloud/firestore": "^5.0.2", + "@google-cloud/firestore": "^6.0.0", "@types/express": "^4.17.6", "@types/passport": "^1.0.3", "compression": "^1.7.4", @@ -76,8 +76,8 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "@types/body-parser": "^1.19.0", "@types/cookie-parser": "^1.4.2", "@types/express-session": "^1.17.2", @@ -88,7 +88,7 @@ "@types/passport-saml": "^1.1.3", "@types/passport-strategy": "^0.2.35", "@types/xml2js": "^0.4.7", - "msw": "^0.44.0", + "msw": "^0.45.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts b/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts index fa7b251780..da67a2f88f 100644 --- a/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts +++ b/plugins/auth-backend/src/identity/DatabaseKeyStore.test.ts @@ -14,10 +14,22 @@ * limitations under the License. */ -import Knex from 'knex'; +import Knex, { Knex as KnexType } from 'knex'; import { DatabaseKeyStore } from './DatabaseKeyStore'; import { DateTime } from 'luxon'; +function createDatabaseManager( + client: KnexType, + skipMigrations: boolean = false, +) { + return { + getClient: async () => client, + migrations: { + skip: skipMigrations, + }, + }; +} + function createDB() { const knex = Knex({ client: 'better-sqlite3', @@ -38,8 +50,10 @@ const keyBase = { describe('DatabaseKeyStore', () => { it('should store a key', async () => { - const database = createDB(); - const store = await DatabaseKeyStore.create({ database }); + const client = createDB(); + const store = await DatabaseKeyStore.create({ + database: createDatabaseManager(client), + }); const key = { kid: '123', @@ -59,8 +73,10 @@ describe('DatabaseKeyStore', () => { }); it('should remove stored keys', async () => { - const database = createDB(); - const store = await DatabaseKeyStore.create({ database }); + const client = createDB(); + const store = await DatabaseKeyStore.create({ + database: createDatabaseManager(client), + }); const key1 = { kid: '1', ...keyBase }; const key2 = { kid: '2', ...keyBase }; diff --git a/plugins/auth-backend/src/identity/DatabaseKeyStore.ts b/plugins/auth-backend/src/identity/DatabaseKeyStore.ts index 6bae1f4412..8039837469 100644 --- a/plugins/auth-backend/src/identity/DatabaseKeyStore.ts +++ b/plugins/auth-backend/src/identity/DatabaseKeyStore.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { resolvePackagePath } from '@backstage/backend-common'; +import { + PluginDatabaseManager, + resolvePackagePath, +} from '@backstage/backend-common'; import { Knex } from 'knex'; import { DateTime } from 'luxon'; import { AnyJWK, KeyStore, StoredKey } from './types'; @@ -33,7 +36,7 @@ type Row = { }; type Options = { - database: Knex; + database: PluginDatabaseManager; }; const parseDate = (date: string | Date) => { @@ -54,29 +57,32 @@ const parseDate = (date: string | Date) => { export class DatabaseKeyStore implements KeyStore { static async create(options: Options): Promise { const { database } = options; + const client = await database.getClient(); - await database.migrate.latest({ - directory: migrationsDir, - }); + if (!database.migrations?.skip) { + await client.migrate.latest({ + directory: migrationsDir, + }); + } - return new DatabaseKeyStore(options); + return new DatabaseKeyStore(client); } - private readonly database: Knex; + private readonly client: Knex; - private constructor(options: Options) { - this.database = options.database; + private constructor(client: Knex) { + this.client = client; } async addKey(key: AnyJWK): Promise { - await this.database(TABLE).insert({ + await this.client(TABLE).insert({ kid: key.kid, key: JSON.stringify(key), }); } async listKeys(): Promise<{ items: StoredKey[] }> { - const rows = await this.database(TABLE).select(); + const rows = await this.client(TABLE).select(); return { items: rows.map(row => ({ @@ -87,6 +93,6 @@ export class DatabaseKeyStore implements KeyStore { } async removeKeys(kids: string[]): Promise { - await this.database(TABLE).delete().whereIn('kid', kids); + await this.client(TABLE).delete().whereIn('kid', kids); } } diff --git a/plugins/auth-backend/src/identity/KeyStores.ts b/plugins/auth-backend/src/identity/KeyStores.ts index 3d238adba9..e29b4b6fc4 100644 --- a/plugins/auth-backend/src/identity/KeyStores.ts +++ b/plugins/auth-backend/src/identity/KeyStores.ts @@ -53,9 +53,7 @@ export class KeyStores { throw new Error('This KeyStore provider requires a database'); } - return await DatabaseKeyStore.create({ - database: await database.getClient(), - }); + return await DatabaseKeyStore.create({ database }); } if (provider === 'memory') { diff --git a/plugins/auth-backend/src/providers/cloudflare-access/index.ts b/plugins/auth-backend/src/providers/cloudflare-access/index.ts new file mode 100644 index 0000000000..10390af7de --- /dev/null +++ b/plugins/auth-backend/src/providers/cloudflare-access/index.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { cfAccess } from './provider'; +export type { + CloudflareAccessClaims, + CloudflareAccessGroup, + CloudflareAccessResult, + CloudflareAccessIdentityProfile, +} from './provider'; diff --git a/plugins/auth-backend/src/providers/cloudflare-access/provider.test.ts b/plugins/auth-backend/src/providers/cloudflare-access/provider.test.ts new file mode 100644 index 0000000000..21ec7371e5 --- /dev/null +++ b/plugins/auth-backend/src/providers/cloudflare-access/provider.test.ts @@ -0,0 +1,267 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import express from 'express'; +import { jwtVerify } from 'jose'; +import { + CF_JWT_HEADER, + CF_AUTH_IDENTITY, + CloudflareAccessAuthProvider, +} from './provider'; +import { AuthResolverContext } from '../types'; +import fetch from 'node-fetch'; + +const jwtMock = jwtVerify as jest.Mocked; +const mockJwt = + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IktFWV9JRCIsImlzcyI6IklTU1VFUl9VUkwifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IlVzZXIgTmFtZSIsImlhdCI6MTUxNjIzOTAyMn0.uMCSBGhij1xn5pnot8XgD-huQuTIBOFGs6kkW_p_X94'; +const mockClaims = { + sub: '1234567890', + email: 'user.name@email.test', + iat: 1632833760, + exp: 1632833763, + iss: 'ISSUER_URL', +}; +const mockCfIdentity = { + name: 'foo', + id: '123', + email: 'foo@bar.com', + groups: [ + { + id: '123', + email: 'foo@bar.com', + name: 'foo', + }, + ], +}; + +const identityOkResponse = { + backstageIdentity: { + identity: { + ownershipEntityRefs: ['user:default/jimmymarkum'], + type: 'user', + userEntityRef: 'user:default/jimmymarkum', + }, + token: + 'eyblob.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iLCJlbnQiOlsidXNlcjpkZWZhdWx0L2ppbW15bWFya3VtIl19.eyblob', + }, + profile: { + email: 'user.name@email.test', + }, + providerInfo: { + cfAccessIdentityProfile: { + email: 'foo@bar.com', + groups: [ + { + email: 'foo@bar.com', + id: '123', + name: 'foo', + }, + ], + id: '123', + name: 'foo', + }, + claims: mockClaims, + expiresInSeconds: 3, + }, +}; + +const mockAuthenticatedUserEmail = 'user.name@email.test'; +const mockCacheClient = { + get: jest.fn(), + set: jest.fn(), + delete: jest.fn(), +}; + +jest.mock('jose'); +jest.mock('node-fetch', () => { + const original = jest.requireActual('node-fetch'); + return { + __esModule: true, + default: jest.fn(), + Headers: original.Headers, + }; +}); + +beforeEach(() => { + jest.clearAllMocks(); +}); + +describe('CloudflareAccessAuthProvider', () => { + // Cloudflare access provides jwt in two ways. + const mockRequestWithJwtHeader = { + header: jest.fn(name => { + if (name === CF_JWT_HEADER) { + return mockJwt; + } else if (name === CF_AUTH_IDENTITY) { + return mockAuthenticatedUserEmail; + } + return undefined; + }), + } as unknown as express.Request; + const mockRequestWithJwtCookie = { + header: jest.fn(_ => { + return undefined; + }), + cookies: { + CF_Authorization: `${mockJwt}`, + }, + } as unknown as express.Request; + + const mockRequestWithoutJwt = { + header: jest.fn(_ => { + return undefined; + }), + } as unknown as express.Request; + + const mockResponse = { + end: jest.fn(), + header: () => jest.fn(), + json: jest.fn(), + status: jest.fn(), + } as unknown as express.Response; + + const mockFetch = fetch as unknown as jest.Mocked; + + const provider = new CloudflareAccessAuthProvider({ + teamName: 'foobar', + resolverContext: {} as AuthResolverContext, + authHandler: async ({ claims }) => ({ + profile: { + email: claims.email, + }, + }), + signInResolver: async () => { + return { + token: + 'eyblob.eyJzdWIiOiJ1c2VyOmRlZmF1bHQvamltbXltYXJrdW0iLCJlbnQiOlsidXNlcjpkZWZhdWx0L2ppbW15bWFya3VtIl19.eyblob', + }; + }, + cache: mockCacheClient, + }); + + describe('when JWT is valid', () => { + it('returns cfidentity also when get-identity succeeds', async () => { + jwtMock.mockReturnValue(Promise.resolve({ payload: mockClaims })); + mockFetch.mockReturnValueOnce( + Promise.resolve({ + ok: true, + status: 200, + json: () => { + return mockCfIdentity; + }, + }), + ); + await provider.refresh(mockRequestWithJwtHeader, mockResponse); + expect(mockResponse.json).toHaveBeenCalledWith(identityOkResponse); + }); + + it('should resolve when passed in cookie', async () => { + jwtMock.mockReturnValue(Promise.resolve({ payload: mockClaims })); + // when mockFetch resolves and there nothing gets returned from /get-identity + mockFetch.mockReturnValueOnce( + Promise.resolve({ + ok: true, + status: 200, + json: () => { + return mockCfIdentity; + }, + }), + ); + await provider.refresh(mockRequestWithJwtCookie, mockResponse); + expect(mockResponse.json).toHaveBeenCalledWith(identityOkResponse); + }); + + it('should resolve an identity and populate access groups when there are groups', async () => { + // when get-identity api responds and responds with status 200 + mockFetch.mockResolvedValueOnce( + Promise.resolve({ + ok: () => { + return true; + }, + status: 200, + json: () => { + return Promise.resolve({ + name: 'foo', + id: '123', + email: 'foo@bar.com', + groups: [ + { + id: '123', + email: 'foo@bar.com', + name: 'foo', + }, + ], + }); + }, + }), + ); + jwtMock.mockReturnValueOnce(Promise.resolve({ payload: mockClaims })); + await provider.refresh(mockRequestWithJwtCookie, mockResponse); + expect(mockResponse.json).toHaveBeenCalledWith(identityOkResponse); + }); + + it('should throw an error when get-identity fails', async () => { + mockFetch.mockReturnValue(Promise.reject()); + await expect( + provider.refresh(mockRequestWithJwtCookie, mockResponse), + ).rejects.toThrowError(); + }); + }); + + describe('should fail when', () => { + it('JWT is missing', async () => { + await expect( + provider.refresh(mockRequestWithoutJwt, mockResponse), + ).rejects.toThrow(); + }); + + it('JWT is invalid', async () => { + jwtMock.mockImplementation(() => { + throw new Error('bad JWT'); + }); + await expect( + provider.refresh(mockRequestWithJwtCookie, mockResponse), + ).rejects.toThrow(); + await expect( + provider.refresh(mockRequestWithJwtHeader, mockResponse), + ).rejects.toThrow(); + jwtMock.mockReset(); + }); + + it('SignInResolver rejects', async () => { + jwtMock.mockReturnValue(mockClaims); + await expect( + provider.refresh(mockRequestWithJwtCookie, mockResponse), + ).rejects.toThrow(); + await expect( + provider.refresh(mockRequestWithJwtHeader, mockResponse), + ).rejects.toThrow(); + jwtMock.mockReset(); + }); + + it('AuthHandler rejects', async () => { + jwtMock.mockReturnValue(mockClaims); + + await expect( + provider.refresh(mockRequestWithJwtCookie, mockResponse), + ).rejects.toThrow(); + await expect( + provider.refresh(mockRequestWithJwtHeader, mockResponse), + ).rejects.toThrow(); + jwtMock.mockReset(); + }); + }); +}); diff --git a/plugins/auth-backend/src/providers/cloudflare-access/provider.ts b/plugins/auth-backend/src/providers/cloudflare-access/provider.ts new file mode 100644 index 0000000000..a2c16fcebf --- /dev/null +++ b/plugins/auth-backend/src/providers/cloudflare-access/provider.ts @@ -0,0 +1,379 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + AuthHandler, + AuthProviderRouteHandlers, + AuthResolverContext, + AuthResponse, + SignInResolver, +} from '../types'; +import fetch, { Headers } from 'node-fetch'; +import express from 'express'; +import * as _ from 'lodash'; +import { jwtVerify, createRemoteJWKSet } from 'jose'; +import { + AuthenticationError, + ResponseError, + ForwardedError, +} from '@backstage/errors'; +import { CacheClient } from '@backstage/backend-common'; +import { createAuthProviderIntegration } from '../createAuthProviderIntegration'; +import { prepareBackstageIdentityResponse } from '../prepareBackstageIdentityResponse'; +import { commonByEmailResolver } from '../resolvers'; + +// JWT Web Token definitions are in the URL below +// https://developers.cloudflare.com/cloudflare-one/identity/users/validating-json/ +export const CF_JWT_HEADER = 'cf-access-jwt-assertion'; +export const CF_AUTH_IDENTITY = 'cf-access-authenticated-user-email'; +const COOKIE_AUTH_NAME = 'CF_Authorization'; +const CACHE_PREFIX = 'providers/cloudflare-access/profile-v1'; + +/** + * Default cache TTL + * + * @public + */ +export const CF_DEFAULT_CACHE_TTL = 3600; + +/** @public */ +export type Options = { + /** + * Access team name + * + * When you configure Access, the public certificates are available at this + * URL, where your-team-name is your team name: + * https://.cloudflareaccess.com/cdn-cgi/access/certs + */ + teamName: string; + authHandler: AuthHandler; + signInResolver: SignInResolver; + resolverContext: AuthResolverContext; + cache?: CacheClient; +}; + +/** + * CloudflareAccessClaims + * + * Can be used in externally provided auth handler or sign in resolver to + * enrich user profile for sign-in user entity + * + * @public + */ +export type CloudflareAccessClaims = { + /** + * `aud` identifies the application to which the JWT is issued. + */ + aud: string[]; + /** + * `email` contains the email address of the authenticated user. + */ + email: string; + /** + * iat and exp are the issuance and expiration timestamps. + */ + exp: number; + iat: number; + /** + * `nonce` is the session identifier. + */ + nonce: string; + /** + * `identity_nonce` is available in the Application Token and can be used to + * query all group membership for a given user. + */ + identity_nonce: string; + /** + * `sub` contains the identifier of the authenticated user. + */ + sub: string; + /** + * `iss` the issuer is the application’s Cloudflare Access Domain URL. + */ + iss: string; + /** + * `custom` contains SAML attributes in the Application Token specified by an + * administrator in the identity provider configuration. + */ + custom: string; +}; + +/** + * CloudflareAccessGroup + * + * @public + */ +export type CloudflareAccessGroup = { + /** + * Group id + */ + id: string; + /** + * Name of group as defined in Cloudflare zero trust dashboard + */ + name: string; + /** + * Access group email address + */ + email: string; +}; + +/** + * CloudflareAccessIdentityProfile + * + * Can be used in externally provided auth handler or sign in resolver to + * enrich user profile for sign-in user entity + * + * @public + */ +export type CloudflareAccessIdentityProfile = { + id: string; + name: string; + email: string; + groups: CloudflareAccessGroup[]; +}; + +/** + * + * @public + */ +export type CloudflareAccessResult = { + claims: CloudflareAccessClaims; + cfIdentity: CloudflareAccessIdentityProfile; + expiresInSeconds?: number; +}; + +/** + * @public + */ +export type CloudflareAccessProviderInfo = { + /** + * Expiry of the access token in seconds. + */ + expiresInSeconds?: number; + /** + * Cloudflare access identity profile with cloudflare access groups + */ + cfAccessIdentityProfile?: CloudflareAccessIdentityProfile; + /** + * Cloudflare access claims + */ + claims: CloudflareAccessClaims; +}; + +export type CloudflareAccessResponse = + AuthResponse; + +export class CloudflareAccessAuthProvider implements AuthProviderRouteHandlers { + private readonly teamName: string; + private readonly resolverContext: AuthResolverContext; + private readonly authHandler: AuthHandler; + private readonly signInResolver: SignInResolver; + private readonly jwtKeySet: any; + private readonly cache?: CacheClient; + + constructor(options: Options) { + this.teamName = options.teamName; + this.authHandler = options.authHandler; + this.signInResolver = options.signInResolver; + this.resolverContext = options.resolverContext; + this.jwtKeySet = createRemoteJWKSet( + new URL( + `https://${this.teamName}.cloudflareaccess.com/cdn-cgi/access/certs`, + ), + ); + this.cache = options.cache; + } + + frameHandler(): Promise { + return Promise.resolve(); + } + + async refresh(req: express.Request, res: express.Response): Promise { + // ProxiedSignInPage calls `/refresh` implicitly each time the backstage + // app is refreshed on the browser. + // User authentication is then checked here. + const result = await this.getResult(req); + const response = await this.handleResult(result); + res.json(response); + } + + start(): Promise { + return Promise.resolve(); + } + + private async getIdentityProfile( + jwt: string, + ): Promise { + const headers = new Headers(); + // set both headers just the way inbound responses are set + headers.set(CF_JWT_HEADER, jwt); + headers.set('cookie', `${COOKIE_AUTH_NAME}=${jwt}`); + try { + const res = await fetch( + `https://${this.teamName}.cloudflareaccess.com/cdn-cgi/access/get-identity`, + { headers }, + ); + if (!res.ok) { + throw ResponseError.fromResponse(res); + } + const cfIdentity = await res.json(); + return cfIdentity as unknown as CloudflareAccessIdentityProfile; + } catch (err) { + throw new ForwardedError('getIdentityProfile failed', err); + } + } + + private async getResult( + req: express.Request, + ): Promise { + // JWTs generated by Access are available in a request header as + // Cf-Access-Jwt-Assertion and as cookies as CF_Authorization. + let jwt = req.header(CF_JWT_HEADER); + if (!jwt) { + jwt = req.cookies.CF_Authorization; + } + if (!jwt) { + // Only throw if both are not provided by Cloudflare Access since either + // can be used. + throw new AuthenticationError( + `Missing ${CF_JWT_HEADER} from Cloudflare Access`, + ); + } + + // Cloudflare signs the JWT using the RSA Signature with SHA-256 (RS256). + // RS256 follows an asymmetric algorithm; a private key signs the JWTs and + // a separate public key verifies the signature. + const verifyResult = await jwtVerify(jwt, this.jwtKeySet, { + issuer: `https://${this.teamName}.cloudflareaccess.com`, + }); + const sub = verifyResult.payload.sub; + const cfAccessResultStr = await this.cache?.get(`${CACHE_PREFIX}/${sub}`); + if (typeof cfAccessResultStr === 'string') { + return JSON.parse(cfAccessResultStr) as CloudflareAccessResult; + } + const claims = verifyResult.payload as CloudflareAccessClaims; + // Builds a passport profile from JWT claims first + try { + // If we successfully fetch the get-identity endpoint, + // We supplement the passport profile with richer user identity + // information here. + const cfIdentity = await this.getIdentityProfile(jwt); + // Stores a stringified JSON object in cfaccess provider cache only when + // we complete all steps + const cfAccessResult: CloudflareAccessResult = { + claims, + cfIdentity, + expiresInSeconds: claims.exp - claims.iat, + }; + this.cache?.set(`${CACHE_PREFIX}/${sub}`, JSON.stringify(cfAccessResult)); + return cfAccessResult; + } catch (err) { + throw new ForwardedError( + 'Failed to populate access identity information', + err, + ); + } + } + + private async handleResult( + result: CloudflareAccessResult, + ): Promise { + const { profile } = await this.authHandler(result, this.resolverContext); + const backstageIdentity = await this.signInResolver( + { + result, + profile, + }, + this.resolverContext, + ); + + return { + providerInfo: { + expiresInSeconds: result.expiresInSeconds, + claims: result.claims, + cfAccessIdentityProfile: result.cfIdentity, + }, + backstageIdentity: prepareBackstageIdentityResponse(backstageIdentity), + profile, + }; + } +} + +/** + * Auth provider integration for Cloudflare Access auth + * + * @public + */ +export const cfAccess = createAuthProviderIntegration({ + create(options: { + /** + * The profile transformation function used to verify and convert the auth response + * into the profile that will be presented to the user. + */ + authHandler?: AuthHandler; + + /** + * Configure sign-in for this provider, without it the provider can not be used to sign users in. + */ + signIn: { + /** + * Maps an auth result to a Backstage identity for the user. + */ + resolver: SignInResolver; + }; + /** + * CacheClient object that was configured for the Backstage backend, + * should be provided via the backend auth plugin. + */ + cache?: CacheClient; + }) { + return ({ config, resolverContext }) => { + const teamName = config.getString('teamName'); + + if (!options.signIn.resolver) { + throw new Error( + 'SignInResolver is required to use this authentication provider', + ); + } + + const authHandler: AuthHandler = + options?.authHandler + ? options.authHandler + : async ({ claims, cfIdentity }) => { + return { + profile: { + email: claims.email, + displayName: cfIdentity.name, + }, + }; + }; + + return new CloudflareAccessAuthProvider({ + teamName, + signInResolver: options?.signIn.resolver, + authHandler, + resolverContext, + ...(options.cache && { cache: options.cache }), + }); + }; + }, + resolvers: { + /** + * Looks up the user by matching their email to the entity email. + */ + emailMatchingUserEntityProfileEmail: () => commonByEmailResolver, + }, +}); diff --git a/plugins/auth-backend/src/providers/index.ts b/plugins/auth-backend/src/providers/index.ts index 41ee44beae..83dd1c6c1f 100644 --- a/plugins/auth-backend/src/providers/index.ts +++ b/plugins/auth-backend/src/providers/index.ts @@ -20,6 +20,12 @@ export type { BitbucketOAuthResult, BitbucketPassportProfile, } from './bitbucket'; +export type { + CloudflareAccessClaims, + CloudflareAccessGroup, + CloudflareAccessResult, + CloudflareAccessIdentityProfile, +} from './cloudflare-access'; export type { GithubOAuthResult } from './github'; export type { OAuth2ProxyResult } from './oauth2-proxy'; export type { OidcAuthResult } from './oidc'; diff --git a/plugins/auth-backend/src/providers/providers.ts b/plugins/auth-backend/src/providers/providers.ts index 71df8223ef..b2795c25f0 100644 --- a/plugins/auth-backend/src/providers/providers.ts +++ b/plugins/auth-backend/src/providers/providers.ts @@ -18,6 +18,7 @@ import { atlassian } from './atlassian'; import { auth0 } from './auth0'; import { awsAlb } from './aws-alb'; import { bitbucket } from './bitbucket'; +import { cfAccess } from './cloudflare-access'; import { gcpIap } from './gcp-iap'; import { github } from './github'; import { gitlab } from './gitlab'; @@ -41,6 +42,7 @@ export const providers = Object.freeze({ auth0, awsAlb, bitbucket, + cfAccess, gcpIap, github, gitlab, diff --git a/plugins/auth-node/CHANGELOG.md b/plugins/auth-node/CHANGELOG.md index 096a4cbcae..c01c24590d 100644 --- a/plugins/auth-node/CHANGELOG.md +++ b/plugins/auth-node/CHANGELOG.md @@ -1,5 +1,29 @@ # @backstage/plugin-auth-node +## 0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## 0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## 0.2.3 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/errors@1.1.0 + ## 0.2.3-next.2 ### Patch Changes diff --git a/plugins/auth-node/package.json b/plugins/auth-node/package.json index c1455535c6..2fd4f470c5 100644 --- a/plugins/auth-node/package.json +++ b/plugins/auth-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-auth-node", - "version": "0.2.3-next.2", + "version": "0.2.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,17 +23,17 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", + "@backstage/backend-common": "^0.15.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", + "@backstage/errors": "^1.1.0", "jose": "^4.6.0", "node-fetch": "^2.6.7", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "lodash": "^4.17.21", - "msw": "^0.44.0", + "msw": "^0.45.0", "uuid": "^8.0.0" }, "files": [ diff --git a/plugins/azure-devops-backend/CHANGELOG.md b/plugins/azure-devops-backend/CHANGELOG.md index 5080410b39..5c8de9557e 100644 --- a/plugins/azure-devops-backend/CHANGELOG.md +++ b/plugins/azure-devops-backend/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-azure-devops-backend +## 0.3.14 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## 0.3.14-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## 0.3.13 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 13a232ec22: Added comments to example to help avoid confusion as to where lines need to be added +- e67c4b7d5a: Adding getProjects endpoint to list out all projects associated with the Azure DevOps organization. + + It can be accessed by using this endpoint `{backendUrl}/api/azure-devops/projects` + +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-azure-devops-common@0.2.4 + ## 0.3.13-next.1 ### Patch Changes diff --git a/plugins/azure-devops-backend/api-report.md b/plugins/azure-devops-backend/api-report.md index eaebea4d7b..900b3c3d12 100644 --- a/plugins/azure-devops-backend/api-report.md +++ b/plugins/azure-devops-backend/api-report.md @@ -18,13 +18,12 @@ import { PullRequestOptions } from '@backstage/plugin-azure-devops-common'; import { RepoBuild } from '@backstage/plugin-azure-devops-common'; import { Team } from '@backstage/plugin-azure-devops-common'; import { TeamMember } from '@backstage/plugin-azure-devops-common'; +import { UrlReader } from '@backstage/backend-common'; import { WebApi } from 'azure-devops-node-api'; -// Warning: (ae-missing-release-tag) "AzureDevOpsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class AzureDevOpsApi { - constructor(logger: Logger, webApi: WebApi); + constructor(logger: Logger, webApi: WebApi, urlReader: UrlReader); // (undocumented) getAllTeams(): Promise; // (undocumented) @@ -73,28 +72,31 @@ export class AzureDevOpsApi { options: PullRequestOptions, ): Promise; // (undocumented) + getReadme( + host: string, + org: string, + project: string, + repo: string, + ): Promise<{ + url: string; + content: string; + }>; + // (undocumented) getRepoBuilds( projectName: string, repoName: string, top: number, ): Promise; // (undocumented) - getTeamMembers({ - projectId, - teamId, - }: { + getTeamMembers(options: { projectId: string; teamId: string; }): Promise; } -// Warning: (ae-missing-release-tag) "createRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function createRouter(options: RouterOptions): Promise; -// Warning: (ae-missing-release-tag) "RouterOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface RouterOptions { // (undocumented) @@ -103,6 +105,8 @@ export interface RouterOptions { config: Config; // (undocumented) logger: Logger; + // (undocumented) + reader: UrlReader; } // (No @packageDocumentation comment for this package) diff --git a/plugins/azure-devops-backend/package.json b/plugins/azure-devops-backend/package.json index f39b4d6a07..0b57991cb9 100644 --- a/plugins/azure-devops-backend/package.json +++ b/plugins/azure-devops-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops-backend", - "version": "0.3.13-next.1", + "version": "0.3.14", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,22 +23,23 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", + "@backstage/backend-common": "^0.15.0", "@backstage/config": "^1.0.1", - "@backstage/plugin-azure-devops-common": "^0.2.4-next.0", + "@backstage/plugin-azure-devops-common": "^0.2.4", "@types/express": "^4.17.6", "azure-devops-node-api": "^11.0.1", "express": "^4.17.1", "express-promise-router": "^4.1.0", "p-limit": "^3.1.0", "winston": "^3.2.1", - "yn": "^4.0.0" + "yn": "^4.0.0", + "mime-types": "^2.1.27" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/supertest": "^2.0.8", "supertest": "^6.1.6", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts index 240ba0b189..2bf2988a98 100644 --- a/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts +++ b/plugins/azure-devops-backend/src/api/AzureDevOpsApi.ts @@ -42,6 +42,8 @@ import { convertDashboardPullRequest, convertPolicy, getArtifactId, + replaceReadme, + buildEncodedUrl, } from '../utils'; import { TeamMember as AdoTeamMember } from 'azure-devops-node-api/interfaces/common/VSSInterfaces'; @@ -52,11 +54,14 @@ import { TeamProjectReference, WebApiTeam, } from 'azure-devops-node-api/interfaces/CoreInterfaces'; +import { UrlReader } from '@backstage/backend-common'; +/** @public */ export class AzureDevOpsApi { public constructor( private readonly logger: Logger, private readonly webApi: WebApi, + private readonly urlReader: UrlReader, ) {} public async getProjects(): Promise { @@ -73,6 +78,7 @@ export class AzureDevOpsApi { a.name && b.name ? a.name.localeCompare(b.name) : 0, ); } + public async getGitRepository( projectName: string, repoName: string, @@ -294,13 +300,11 @@ export class AzureDevOpsApi { ); } - public async getTeamMembers({ - projectId, - teamId, - }: { + public async getTeamMembers(options: { projectId: string; teamId: string; }): Promise { + const { projectId, teamId } = options; this.logger?.debug(`Getting team member ids for team '${teamId}'.`); const client = await this.webApi.getCoreApi(); @@ -393,6 +397,28 @@ export class AzureDevOpsApi { return buildRuns; } + + public async getReadme( + host: string, + org: string, + project: string, + repo: string, + ): Promise<{ + url: string; + content: string; + }> { + const url = buildEncodedUrl(host, org, project, repo, 'README.md'); + const response = await this.urlReader.read(url); + const content = await replaceReadme( + this.urlReader, + host, + org, + project, + repo, + response.toString(), + ); + return { url, content }; + } } export function mappedRepoBuild(build: Build): RepoBuild { diff --git a/plugins/azure-devops-backend/src/service/router.test.ts b/plugins/azure-devops-backend/src/service/router.test.ts index 3bf18de6a2..a77600feb0 100644 --- a/plugins/azure-devops-backend/src/service/router.test.ts +++ b/plugins/azure-devops-backend/src/service/router.test.ts @@ -33,7 +33,7 @@ import { ConfigReader } from '@backstage/config'; import { GitRepository } from 'azure-devops-node-api/interfaces/GitInterfaces'; import { createRouter } from './router'; import express from 'express'; -import { getVoidLogger } from '@backstage/backend-common'; +import { getVoidLogger, UrlReaders } from '@backstage/backend-common'; import request from 'supertest'; describe('createRouter', () => { @@ -53,19 +53,30 @@ describe('createRouter', () => { getBuildRuns: jest.fn(), getAllTeams: jest.fn(), getTeamMembers: jest.fn(), + getReadme: jest.fn(), } as any; + + const config = new ConfigReader({ + azureDevOps: { + token: 'foo', + host: 'host.com', + organization: 'myOrg', + top: 5, + }, + }); + + const logger = getVoidLogger(); + const router = await createRouter({ + config, + logger, azureDevOpsApi, - logger: getVoidLogger(), - config: new ConfigReader({ - azureDevOps: { - token: 'foo', - host: 'host.com', - organization: 'myOrg', - top: 5, - }, + reader: UrlReaders.default({ + config, + logger, }), }); + app = express().use(router); }); @@ -455,4 +466,67 @@ describe('createRouter', () => { expect(response.status).toEqual(200); }); }); + + describe('GET /readme/:projectName/:repoName', () => { + it('fetches readme file', async () => { + const content = getReadmeMock(); + const url = `https://host.com/myOrg/myProject/_git/myRepo?path=README.md`; + + azureDevOpsApi.getReadme.mockResolvedValueOnce({ + content, + url, + }); + + const response = await request(app).get( + '/readme/myProject/myRepo?path=README.md', + ); + expect(azureDevOpsApi.getReadme).toHaveBeenCalledWith( + 'host.com', + 'myOrg', + 'myProject', + 'myRepo', + ); + expect(response.status).toEqual(200); + expect(response.body).toEqual({ + content, + url, + }); + }); + }); }); + +function getReadmeMock() { + return ` + # Introduction + TODO: Give a short introduction of your project. Let this section explain the objectives or the motivation behind this project. + + # Getting Started + TODO: Guide users through getting your code up and running on their own system. In this section you can talk about: + 1. Installation process + 2. Software dependencies + 3. Latest releases + 4. API references + + # Build and Test + TODO: Describe and show how to build your code and run the tests. + + # Contribute + TODO: Explain how other users and developers can contribute to make your code better. + + If you want to learn more about creating good readme files then refer the following [guidelines](https://docs.microsoft.com/en-us/azure/devops/repos/git/create-a-readme?view=azure-devops). You can also seek inspiration from the below readme files: + - [ASP.NET Core](https://github.com/aspnet/Home) + - [Visual Studio Code](https://github.com/Microsoft/vscode) + - [Chakra Core](https://github.com/Microsoft/ChakraCore) + + + - ![Imagem 1](./images/image1.jpg) + - ![Imagem 2](./images/image2.png) + - ![Imagem 3](./images/image3.jpg) + - ![Imagem 4](./images/image4.webp) + - ![Imagem 5](./images/image5.png) + - ![Imagem 6](/images/image6.png) + - ![Imagem 7](/images/image-7.jpg) + - ![Imagem 8](./images/image-8.gif) + - ![Imagem 9](/images/image9.png) + `; +} diff --git a/plugins/azure-devops-backend/src/service/router.ts b/plugins/azure-devops-backend/src/service/router.ts index a4a76b4a14..b6b8a6fdea 100644 --- a/plugins/azure-devops-backend/src/service/router.ts +++ b/plugins/azure-devops-backend/src/service/router.ts @@ -26,21 +26,24 @@ import { Config } from '@backstage/config'; import { Logger } from 'winston'; import { PullRequestsDashboardProvider } from '../api/PullRequestsDashboardProvider'; import Router from 'express-promise-router'; -import { errorHandler } from '@backstage/backend-common'; +import { errorHandler, UrlReader } from '@backstage/backend-common'; import express from 'express'; const DEFAULT_TOP = 10; +/** @public */ export interface RouterOptions { azureDevOpsApi?: AzureDevOpsApi; logger: Logger; config: Config; + reader: UrlReader; } +/** @public */ export async function createRouter( options: RouterOptions, ): Promise { - const { logger } = options; + const { logger, reader } = options; const config = options.config.getConfig('azureDevOps'); const token = config.getString('token'); @@ -51,7 +54,7 @@ export async function createRouter( const webApi = new WebApi(`https://${host}/${organization}`, authHandler); const azureDevOpsApi = - options.azureDevOpsApi || new AzureDevOpsApi(logger, webApi); + options.azureDevOpsApi || new AzureDevOpsApi(logger, webApi, reader); const pullRequestsDashboardProvider = await PullRequestsDashboardProvider.create(logger, azureDevOpsApi); @@ -191,6 +194,17 @@ export async function createRouter( res.status(200).json(teamIds); }); + router.get('/readme/:projectName/:repoName', async (req, res) => { + const { projectName, repoName } = req.params; + const readme = await azureDevOpsApi.getReadme( + host, + organization, + projectName, + repoName, + ); + res.status(200).json(readme); + }); + router.use(errorHandler()); return router; } diff --git a/plugins/azure-devops-backend/src/service/standaloneServer.ts b/plugins/azure-devops-backend/src/service/standaloneServer.ts index 1d5889fcf1..e2f4aa4986 100644 --- a/plugins/azure-devops-backend/src/service/standaloneServer.ts +++ b/plugins/azure-devops-backend/src/service/standaloneServer.ts @@ -17,6 +17,7 @@ import { createServiceBuilder, loadBackendConfig, + UrlReaders, } from '@backstage/backend-common'; import { Server } from 'http'; import { Logger } from 'winston'; @@ -39,6 +40,7 @@ export async function startStandaloneServer( const router = await createRouter({ logger, config, + reader: UrlReaders.default({ logger, config }), }); let service = createServiceBuilder(module) diff --git a/plugins/azure-devops-backend/src/utils/azure-devops-utils.test.ts b/plugins/azure-devops-backend/src/utils/azure-devops-utils.test.ts index 8aed436710..f044a20968 100644 --- a/plugins/azure-devops-backend/src/utils/azure-devops-utils.test.ts +++ b/plugins/azure-devops-backend/src/utils/azure-devops-utils.test.ts @@ -21,12 +21,15 @@ import { } from '@backstage/plugin-azure-devops-common'; import { convertDashboardPullRequest, + extractAssets, + extractPartsFromAsset, getArtifactId, getAvatarUrl, getPullRequestLink, + replaceReadme, } from './azure-devops-utils'; - import { GitPullRequest } from 'azure-devops-node-api/interfaces/GitInterfaces'; +import { UrlReader } from '@backstage/backend-common'; describe('convertDashboardPullRequest', () => { it('should return DashboardPullRequest', () => { @@ -159,3 +162,115 @@ describe('getArtifactId', () => { expect(result).toBe('vstfs:///CodeReview/CodeReviewId/project1/1'); }); }); + +describe('extractAssets', () => { + it('should return assets', () => { + const readme = ` + ## Images + ![Image 1](./images/sample-4(2).png) + ![Image 2](./images/cdCSj+-012340.jpg) + ![Image 3](/images/test-4(2)))).jpeg) + ![Image 4](./images/test-2211jd.webp) + ![Image 5](/images/sa)mple.gif) + `; + const result = extractAssets(readme); + expect(result).toEqual([ + '[Image 1](./images/sample-4(2).png)', + '[Image 2](./images/cdCSj+-012340.jpg)', + '[Image 3](/images/test-4(2)))).jpeg)', + '[Image 4](./images/test-2211jd.webp)', + '[Image 5](/images/sa)mple.gif)', + ]); + }); +}); + +describe('extractPartsFromAsset', () => { + it('should return parts from asset - PNG', () => { + const result = extractPartsFromAsset('[Image 1](./images/sample-4(2).png)'); + expect(result).toEqual({ + label: 'Image 1', + path: '/images/sample-4(2)', + ext: '.png', + }); + }); + + it('should return parts from asset - JPG', () => { + const result = extractPartsFromAsset( + '[Image 2](./images/cdCSj+-012340.jpg)', + ); + expect(result).toEqual({ + label: 'Image 2', + path: '/images/cdCSj+-012340', + ext: '.jpg', + }); + }); + + it('should return parts from asset - JPEG', () => { + const result = extractPartsFromAsset( + '[Image 2](/images/test-4(2)))).jpeg)', + ); + expect(result).toEqual({ + label: 'Image 2', + path: '/images/test-4(2))))', + ext: '.jpeg', + }); + }); + + it('should return parts from asset - WEBP', () => { + const result = extractPartsFromAsset('[Image 2](/images/test-2211jd.webp)'); + expect(result).toEqual({ + label: 'Image 2', + path: '/images/test-2211jd', + ext: '.webp', + }); + }); + + it('should return parts from asset - GIF', () => { + const result = extractPartsFromAsset('[Image 2](/images/test-4(2)))).gif)'); + expect(result).toEqual({ + label: 'Image 2', + path: '/images/test-4(2))))', + ext: '.gif', + }); + }); +}); + +describe('replaceReadme', () => { + it('should return mime type', async () => { + const readme = ` + ## Images + ![Image 1](./images/sample-4(2).png) + ![Image 2](./images/cdCSj+-012340.jpg) + ![Image 3](/images/test-4(2)))).jpeg) + ![Image 4](./images/test-2211jd.webp) + ![Image 5](/images/sa)mple.gif) + `; + + const reader: UrlReader = { + read: url => new Promise(resolve => resolve(Buffer.from(url))), + readTree: jest.fn(), + search: jest.fn(), + readUrl: jest.fn(), + }; + + const result = await replaceReadme( + reader, + 'host', + 'org', + 'project', + 'repo', + readme, + ); + + const expected = ` + ## Images + ![Image 1](data:image/png;base64,aHR0cHM6Ly9ob3N0L29yZy9wcm9qZWN0L19naXQvcmVwbz9wYXRoPSUyRmltYWdlcyUyRnNhbXBsZS00KDIpLnBuZw==) + ![Image 2](data:image/jpeg;base64,aHR0cHM6Ly9ob3N0L29yZy9wcm9qZWN0L19naXQvcmVwbz9wYXRoPSUyRmltYWdlcyUyRmNkQ1NqJTJCLTAxMjM0MC5qcGc=) + ![Image 3](data:image/jpeg;base64,aHR0cHM6Ly9ob3N0L29yZy9wcm9qZWN0L19naXQvcmVwbz9wYXRoPSUyRmltYWdlcyUyRnRlc3QtNCgyKSkpKS5qcGVn) + ![Image 4](data:image/webp;base64,aHR0cHM6Ly9ob3N0L29yZy9wcm9qZWN0L19naXQvcmVwbz9wYXRoPSUyRmltYWdlcyUyRnRlc3QtMjIxMWpkLndlYnA=) + ![Image 5](data:image/gif;base64,aHR0cHM6Ly9ob3N0L29yZy9wcm9qZWN0L19naXQvcmVwbz9wYXRoPSUyRmltYWdlcyUyRnNhKW1wbGUuZ2lm) + `; + + expect(expected).toBe(result); + }); +}); diff --git a/plugins/azure-devops-backend/src/utils/azure-devops-utils.ts b/plugins/azure-devops-backend/src/utils/azure-devops-utils.ts index 7a0d0a279e..191486a925 100644 --- a/plugins/azure-devops-backend/src/utils/azure-devops-utils.ts +++ b/plugins/azure-devops-backend/src/utils/azure-devops-utils.ts @@ -30,9 +30,11 @@ import { GitRepository, IdentityRefWithVote, } from 'azure-devops-node-api/interfaces/GitInterfaces'; +import mime from 'mime-types'; import { IdentityRef } from 'azure-devops-node-api/interfaces/common/VSSInterfaces'; import { PolicyEvaluationRecord } from 'azure-devops-node-api/interfaces/PolicyInterfaces'; +import { UrlReader } from '@backstage/backend-common'; export function convertDashboardPullRequest( pullRequest: GitPullRequest, @@ -205,6 +207,48 @@ export function convertPolicy( }; } +export async function replaceReadme( + urlReader: UrlReader, + host: string, + org: string, + project: string, + repo: string, + readmeContent: string, +) { + const filesPath = extractAssets(readmeContent); + if (!filesPath) return readmeContent; + return await filesPath.reduce( + async (promise: Promise, filePath: string) => + promise.then(async content => { + const { label, path, ext } = extractPartsFromAsset(filePath); + const data = mime.lookup(ext); + const url = buildEncodedUrl(host, org, project, repo, path + ext); + const buffer = await urlReader.read(url); + const file = await buffer.toString('base64'); + return content.replace( + filePath, + `[${label}](data:${data};base64,${file})`, + ); + }), + Promise.resolve(readmeContent), + ); +} + +export function buildEncodedUrl( + host: string, + org: string, + project: string, + repo: string, + path: string, +): string { + const encodedHost = encodeURIComponent(host); + const encodedOrg = encodeURIComponent(org); + const encodedProject = encodeURIComponent(project); + const encodedRepo = encodeURIComponent(repo); + const encodedPath = encodeURIComponent(path); + return `https://${encodedHost}/${encodedOrg}/${encodedProject}/_git/${encodedRepo}?path=${encodedPath}`; +} + function convertReviewer( identityRef?: IdentityRefWithVote, ): Reviewer | undefined { @@ -263,3 +307,24 @@ function convertCreatedBy(identityRef?: IdentityRef): CreatedBy | undefined { function hasAutoComplete(pullRequest: GitPullRequest): boolean { return pullRequest.isDraft !== true && !!pullRequest.completionOptions; } + +export function extractAssets(content: string) { + const regExp = + /\[([^\[\]]*)\]\((?!https?:\/\/)(.*?)(\.png|\.jpg|\.jpeg|\.gif|\.webp)(.*)\)/gim; + return content.match(regExp); +} + +export function extractPartsFromAsset(content: string): { + label: string; + path: string; + ext: string; +} { + const regExp = + /\[(.*?)\]\((?!https?:\/\/)(.*?)(\.png|\.jpg|\.jpeg|\.gif|\.webp)(.*)\)/; + const [_, label, path, ext] = regExp.exec(content) || []; + return { + ext, + label, + path: path.startsWith('.') ? path.substring(1, path.length) : path, + }; +} diff --git a/plugins/azure-devops-common/CHANGELOG.md b/plugins/azure-devops-common/CHANGELOG.md index 8320047ea1..cdd02cc625 100644 --- a/plugins/azure-devops-common/CHANGELOG.md +++ b/plugins/azure-devops-common/CHANGELOG.md @@ -1,5 +1,13 @@ # @backstage/plugin-azure-devops-common +## 0.2.4 + +### Patch Changes + +- e67c4b7d5a: Adding getProjects endpoint to list out all projects associated with the Azure DevOps organization. + + It can be accessed by using this endpoint `{backendUrl}/api/azure-devops/projects` + ## 0.2.4-next.0 ### Patch Changes diff --git a/plugins/azure-devops-common/api-report.md b/plugins/azure-devops-common/api-report.md index 34d911dac6..ea9f7130c0 100644 --- a/plugins/azure-devops-common/api-report.md +++ b/plugins/azure-devops-common/api-report.md @@ -3,8 +3,6 @@ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). ```ts -// Warning: (ae-missing-release-tag) "BuildResult" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export enum BuildResult { Canceled = 32, @@ -14,8 +12,6 @@ export enum BuildResult { Succeeded = 2, } -// Warning: (ae-missing-release-tag) "BuildRun" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type BuildRun = { id?: number; @@ -30,15 +26,11 @@ export type BuildRun = { uniqueName?: string; }; -// Warning: (ae-missing-release-tag) "BuildRunOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type BuildRunOptions = { top?: number; }; -// Warning: (ae-missing-release-tag) "BuildStatus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export enum BuildStatus { All = 47, @@ -50,8 +42,6 @@ export enum BuildStatus { Postponed = 8, } -// Warning: (ae-missing-release-tag) "CreatedBy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface CreatedBy { // (undocumented) @@ -68,8 +58,6 @@ export interface CreatedBy { uniqueName?: string; } -// Warning: (ae-missing-release-tag) "DashboardPullRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface DashboardPullRequest { // (undocumented) @@ -98,8 +86,6 @@ export interface DashboardPullRequest { title?: string; } -// Warning: (ae-missing-release-tag) "GitTag" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type GitTag = { objectId?: string; @@ -110,8 +96,6 @@ export type GitTag = { commitLink: string; }; -// Warning: (ae-missing-release-tag) "Policy" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface Policy { // (undocumented) @@ -126,9 +110,7 @@ export interface Policy { type: PolicyType; } -// Warning: (ae-missing-release-tag) "PolicyEvaluationStatus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public +// @public (undocumented) export enum PolicyEvaluationStatus { Approved = 2, Broken = 5, @@ -138,8 +120,6 @@ export enum PolicyEvaluationStatus { Running = 1, } -// Warning: (ae-missing-release-tag) "PolicyType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export enum PolicyType { // (undocumented) @@ -156,8 +136,6 @@ export enum PolicyType { Status = 'Status', } -// Warning: (ae-missing-release-tag) "PolicyTypeId" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export enum PolicyTypeId { Build = '0609b952-1397-4640-95ec-e00a01b2c241', @@ -168,8 +146,6 @@ export enum PolicyTypeId { Status = 'cbdc66da-9728-4af8-aada-9a5a32e4a226', } -// Warning: (ae-missing-release-tag) "Project" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type Project = { id?: string; @@ -177,8 +153,6 @@ export type Project = { description?: string; }; -// Warning: (ae-missing-release-tag) "PullRequest" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type PullRequest = { pullRequestId?: number; @@ -194,16 +168,12 @@ export type PullRequest = { link: string; }; -// Warning: (ae-missing-release-tag) "PullRequestOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type PullRequestOptions = { top: number; status: PullRequestStatus; }; -// Warning: (ae-missing-release-tag) "PullRequestStatus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export enum PullRequestStatus { Abandoned = 2, @@ -213,8 +183,6 @@ export enum PullRequestStatus { NotSet = 0, } -// Warning: (ae-missing-release-tag) "PullRequestVoteStatus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export enum PullRequestVoteStatus { // (undocumented) @@ -229,8 +197,22 @@ export enum PullRequestVoteStatus { WaitingForAuthor = -5, } -// Warning: (ae-missing-release-tag) "RepoBuild" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public (undocumented) +export interface Readme { + // (undocumented) + content: string; + // (undocumented) + url: string; +} + +// @public (undocumented) +export interface ReadmeConfig { + // (undocumented) + project: string; + // (undocumented) + repo: string; +} + // @public (undocumented) export type RepoBuild = { id?: number; @@ -245,15 +227,11 @@ export type RepoBuild = { uniqueName?: string; }; -// Warning: (ae-missing-release-tag) "RepoBuildOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type RepoBuildOptions = { top?: number; }; -// Warning: (ae-missing-release-tag) "Repository" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface Repository { // (undocumented) @@ -264,8 +242,6 @@ export interface Repository { url?: string; } -// Warning: (ae-missing-release-tag) "Reviewer" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface Reviewer { // (undocumented) @@ -284,8 +260,6 @@ export interface Reviewer { voteStatus: PullRequestVoteStatus; } -// Warning: (ae-missing-release-tag) "Team" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface Team { // (undocumented) @@ -300,8 +274,6 @@ export interface Team { projectName?: string; } -// Warning: (ae-missing-release-tag) "TeamMember" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface TeamMember { // (undocumented) diff --git a/plugins/azure-devops-common/package.json b/plugins/azure-devops-common/package.json index 9ab17220c2..40803ae633 100644 --- a/plugins/azure-devops-common/package.json +++ b/plugins/azure-devops-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops-common", - "version": "0.2.4-next.0", + "version": "0.2.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,7 +32,7 @@ "clean": "backstage-cli package clean" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3" + "@backstage/cli": "^0.18.1-next.0" }, "files": [ "dist" diff --git a/plugins/azure-devops-common/src/types.ts b/plugins/azure-devops-common/src/types.ts index db2813dec1..380cb3e585 100644 --- a/plugins/azure-devops-common/src/types.ts +++ b/plugins/azure-devops-common/src/types.ts @@ -14,6 +14,7 @@ * limitations under the License. */ +/** @public */ export enum BuildResult { /** * No result @@ -37,6 +38,7 @@ export enum BuildResult { Canceled = 32, } +/** @public */ export enum BuildStatus { /** * No status. @@ -68,6 +70,7 @@ export enum BuildStatus { All = 47, } +/** @public */ export type RepoBuild = { id?: number; title: string; @@ -81,10 +84,12 @@ export type RepoBuild = { uniqueName?: string; }; +/** @public */ export type RepoBuildOptions = { top?: number; }; +/** @public */ export enum PullRequestStatus { /** * Status not set. Default state. @@ -108,6 +113,7 @@ export enum PullRequestStatus { All = 4, } +/** @public */ export type GitTag = { objectId?: string; peeledObjectId?: string; @@ -117,6 +123,7 @@ export type GitTag = { commitLink: string; }; +/** @public */ export type PullRequest = { pullRequestId?: number; repoName?: string; @@ -131,11 +138,13 @@ export type PullRequest = { link: string; }; +/** @public */ export type PullRequestOptions = { top: number; status: PullRequestStatus; }; +/** @public */ export interface DashboardPullRequest { pullRequestId?: number; title?: string; @@ -151,6 +160,7 @@ export interface DashboardPullRequest { link?: string; } +/** @public */ export interface Reviewer { id?: string; displayName?: string; @@ -161,6 +171,7 @@ export interface Reviewer { voteStatus: PullRequestVoteStatus; } +/** @public */ export interface Policy { id?: number; type: PolicyType; @@ -169,6 +180,7 @@ export interface Policy { link?: string; } +/** @public */ export interface CreatedBy { id?: string; displayName?: string; @@ -178,12 +190,14 @@ export interface CreatedBy { teamNames?: string[]; } +/** @public */ export interface Repository { id?: string; name?: string; url?: string; } +/** @public */ export interface Team { id?: string; name?: string; @@ -192,6 +206,19 @@ export interface Team { members?: string[]; } +/** @public */ +export interface ReadmeConfig { + project: string; + repo: string; +} + +/** @public */ +export interface Readme { + url: string; + content: string; +} + +/** @public */ export interface TeamMember { id?: string; displayName?: string; @@ -202,6 +229,7 @@ export interface TeamMember { /** * Status of a policy which is running against a specific pull request. */ +/** @public */ export enum PolicyEvaluationStatus { /** * The policy is either queued to run, or is waiting for some event before progressing. @@ -229,6 +257,7 @@ export enum PolicyEvaluationStatus { Broken = 5, } +/** @public */ export enum PolicyType { Build = 'Build', Status = 'Status', @@ -238,6 +267,7 @@ export enum PolicyType { MergeStrategy = 'MergeStrategy', } +/** @public */ export enum PolicyTypeId { /** * This policy will require a successful build has been performed before updating protected refs. @@ -265,6 +295,7 @@ export enum PolicyTypeId { MergeStrategy = 'fa4e907d-c16b-4a4c-9dfa-4916e5d171ab', } +/** @public */ export enum PullRequestVoteStatus { Approved = 10, ApprovedWithSuggestions = 5, @@ -272,6 +303,8 @@ export enum PullRequestVoteStatus { WaitingForAuthor = -5, Rejected = -10, } + +/** @public */ export type BuildRun = { id?: number; title: string; @@ -285,10 +318,12 @@ export type BuildRun = { uniqueName?: string; }; +/** @public */ export type BuildRunOptions = { top?: number; }; +/** @public */ export type Project = { id?: string; name?: string; diff --git a/plugins/azure-devops/CHANGELOG.md b/plugins/azure-devops/CHANGELOG.md index 15a6f1df08..f108dd1424 100644 --- a/plugins/azure-devops/CHANGELOG.md +++ b/plugins/azure-devops/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/plugin-azure-devops +## 0.1.24 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.1.24-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.1.24-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.23 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- e049e41048: Exporting azureDevOpsApiRef, AzureGitTagsIcon, and all hooks for the benefit of other plugins. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + - @backstage/plugin-azure-devops-common@0.2.4 + ## 0.1.23-next.3 ### Patch Changes diff --git a/plugins/azure-devops/README.md b/plugins/azure-devops/README.md index 68d2b57afc..5079fa4f16 100644 --- a/plugins/azure-devops/README.md +++ b/plugins/azure-devops/README.md @@ -22,6 +22,12 @@ Lists all Git Tags for a given repository ![Azure Repos Git Tags Example](./docs/azure-devops-git-tags.png) +### Azure Readme + +Readme for a given repository + +![Azure Readme Example](./docs/azure-devops-readme.png) + ## Setup The following sections will help you get the Azure DevOps plugin setup and running @@ -70,7 +76,7 @@ In this case `` will be the name of your Team Project and ` + + + + ... + + + + + + + + ); + ``` + +**Notes:** + +- You'll need to add the `EntitySwitch.Case` above from step 2 to all the entity sections you want to see Readme in. For example if you wanted to see Readme when looking at Website entities then you would need to add this to the `websiteEntityPage` section. +- The `if` prop is optional on the `EntitySwitch.Case`, you can remove it if you always want to see the tab even if the entity being viewed does not have the needed annotation +- The `maxHeight` property on the `EntityAzureReadmeCard` will set the maximum screen size you would like to see, if not set it will default to 100% + ## Limitations - Currently multiple organizations are not supported diff --git a/plugins/azure-devops/api-report.md b/plugins/azure-devops/api-report.md index b366166d95..d083d00dba 100644 --- a/plugins/azure-devops/api-report.md +++ b/plugins/azure-devops/api-report.md @@ -16,28 +16,24 @@ import { GitTag } from '@backstage/plugin-azure-devops-common'; import { IdentityApi } from '@backstage/core-plugin-api'; import { PullRequest } from '@backstage/plugin-azure-devops-common'; import { PullRequestOptions } from '@backstage/plugin-azure-devops-common'; +import { Readme } from '@backstage/plugin-azure-devops-common'; +import { ReadmeConfig } from '@backstage/plugin-azure-devops-common'; import { RepoBuild } from '@backstage/plugin-azure-devops-common'; import { RepoBuildOptions } from '@backstage/plugin-azure-devops-common'; import { SvgIconProps } from '@material-ui/core'; import { Team } from '@backstage/plugin-azure-devops-common'; -// Warning: (ae-missing-release-tag) "AllFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type AllFilter = BaseFilter & { type: FilterType.All; }; -// Warning: (ae-missing-release-tag) "AssignedToTeamFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type AssignedToTeamFilter = BaseFilter & { type: FilterType.AssignedToTeam; teamId: string; }; -// Warning: (ae-missing-release-tag) "AssignedToTeamsFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type AssignedToTeamsFilter = BaseFilter & ( @@ -51,8 +47,6 @@ export type AssignedToTeamsFilter = BaseFilter & } ); -// Warning: (ae-missing-release-tag) "AssignedToUserFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type AssignedToUserFilter = BaseFilter & ( @@ -66,8 +60,6 @@ export type AssignedToUserFilter = BaseFilter & } ); -// Warning: (ae-missing-release-tag) "AzureDevOpsApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface AzureDevOpsApi { // (undocumented) @@ -101,6 +93,8 @@ export interface AzureDevOpsApi { items: PullRequest[]; }>; // (undocumented) + getReadme(opts: ReadmeConfig): Promise; + // (undocumented) getRepoBuilds( projectName: string, repoName: string, @@ -112,13 +106,9 @@ export interface AzureDevOpsApi { getUserTeamIds(userId: string): Promise; } -// Warning: (ae-missing-release-tag) "azureDevOpsApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const azureDevOpsApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "AzureDevOpsClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class AzureDevOpsClient implements AzureDevOpsApi { constructor(options: { @@ -156,6 +146,8 @@ export class AzureDevOpsClient implements AzureDevOpsApi { items: PullRequest[]; }>; // (undocumented) + getReadme(opts: ReadmeConfig): Promise; + // (undocumented) getRepoBuilds( projectName: string, repoName: string, @@ -167,38 +159,24 @@ export class AzureDevOpsClient implements AzureDevOpsApi { getUserTeamIds(userId: string): Promise; } -// Warning: (ae-missing-release-tag) "azureDevOpsPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const azureDevOpsPlugin: BackstagePlugin<{}, {}>; +export const azureDevOpsPlugin: BackstagePlugin<{}, {}, {}>; -// Warning: (ae-missing-release-tag) "AzurePullRequestsIcon" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const AzurePullRequestsIcon: (props: SvgIconProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "AzurePullRequestsPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const AzurePullRequestsPage: ({ - projectName, - pollingInterval, - defaultColumnConfigs, -}: { +export const AzurePullRequestsPage: (props: { projectName?: string | undefined; pollingInterval?: number | undefined; defaultColumnConfigs?: PullRequestColumnConfig[] | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "BaseFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type BaseFilter = { type: FilterType; }; -// Warning: (ae-missing-release-tag) "CreatedByTeamFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type CreatedByTeamFilter = BaseFilter & ({ @@ -212,8 +190,6 @@ export type CreatedByTeamFilter = BaseFilter & } )); -// Warning: (ae-missing-release-tag) "CreatedByTeamsFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type CreatedByTeamsFilter = BaseFilter & ( @@ -233,8 +209,6 @@ export type CreatedByTeamsFilter = BaseFilter & } ); -// Warning: (ae-missing-release-tag) "CreatedByUserFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type CreatedByUserFilter = BaseFilter & ( @@ -248,31 +222,24 @@ export type CreatedByUserFilter = BaseFilter & } ); -// Warning: (ae-missing-release-tag) "EntityAzureGitTagsContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const EntityAzureGitTagsContent: () => JSX.Element; -// Warning: (ae-missing-release-tag) "EntityAzurePipelinesContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityAzurePipelinesContent: ({ - defaultLimit, -}: { +export const EntityAzurePipelinesContent: (props: { defaultLimit?: number | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "EntityAzurePullRequestsContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityAzurePullRequestsContent: ({ - defaultLimit, -}: { +export const EntityAzurePullRequestsContent: (props: { defaultLimit?: number | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "Filter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// +// @public (undocumented) +export const EntityAzureReadmeCard: (props: { + maxHeight?: number | undefined; +}) => JSX.Element; + // @public (undocumented) export type Filter = | AssignedToUserFilter @@ -283,8 +250,6 @@ export type Filter = | CreatedByTeamsFilter | AllFilter; -// Warning: (ae-missing-release-tag) "FilterType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export enum FilterType { // (undocumented) @@ -311,18 +276,12 @@ export enum FilterType { CreatedByUser = 'CreatedByUser', } -// Warning: (ae-missing-release-tag) "isAzureDevOpsAvailable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const isAzureDevOpsAvailable: (entity: Entity) => boolean; -// Warning: (ae-missing-release-tag) "isAzurePipelinesAvailable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const isAzurePipelinesAvailable: (entity: Entity) => boolean; -// Warning: (ae-missing-release-tag) "PullRequestColumnConfig" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface PullRequestColumnConfig { // (undocumented) @@ -333,8 +292,6 @@ export interface PullRequestColumnConfig { title: string; } -// Warning: (ae-missing-release-tag) "PullRequestFilter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type PullRequestFilter = (pullRequest: DashboardPullRequest) => boolean; diff --git a/plugins/azure-devops/docs/azure-devops-readme.png b/plugins/azure-devops/docs/azure-devops-readme.png new file mode 100644 index 0000000000..cac087f685 Binary files /dev/null and b/plugins/azure-devops/docs/azure-devops-readme.png differ diff --git a/plugins/azure-devops/package.json b/plugins/azure-devops/package.json index f2f3ee1e2f..af2e47532f 100644 --- a/plugins/azure-devops/package.json +++ b/plugins/azure-devops/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-azure-devops", - "version": "0.1.23-next.3", + "version": "0.1.24", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,13 +30,13 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-azure-devops-common": "^0.2.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-azure-devops-common": "^0.2.4", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -49,17 +49,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/azure-devops/src/api/AzureDevOpsApi.ts b/plugins/azure-devops/src/api/AzureDevOpsApi.ts index ccedc401f1..ce6a3cac39 100644 --- a/plugins/azure-devops/src/api/AzureDevOpsApi.ts +++ b/plugins/azure-devops/src/api/AzureDevOpsApi.ts @@ -21,6 +21,8 @@ import { GitTag, PullRequest, PullRequestOptions, + Readme, + ReadmeConfig, RepoBuild, RepoBuildOptions, Team, @@ -28,10 +30,12 @@ import { import { createApiRef } from '@backstage/core-plugin-api'; +/** @public */ export const azureDevOpsApiRef = createApiRef({ id: 'plugin.azure-devops.service', }); +/** @public */ export interface AzureDevOpsApi { getRepoBuilds( projectName: string, @@ -64,4 +68,6 @@ export interface AzureDevOpsApi { definitionName?: string, options?: BuildRunOptions, ): Promise<{ items: BuildRun[] }>; + + getReadme(opts: ReadmeConfig): Promise; } diff --git a/plugins/azure-devops/src/api/AzureDevOpsClient.ts b/plugins/azure-devops/src/api/AzureDevOpsClient.ts index 61c8479d71..68d8896538 100644 --- a/plugins/azure-devops/src/api/AzureDevOpsClient.ts +++ b/plugins/azure-devops/src/api/AzureDevOpsClient.ts @@ -21,15 +21,17 @@ import { GitTag, PullRequest, PullRequestOptions, + Readme, + ReadmeConfig, RepoBuild, RepoBuildOptions, Team, } from '@backstage/plugin-azure-devops-common'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; - -import { AzureDevOpsApi } from './AzureDevOpsApi'; import { ResponseError } from '@backstage/errors'; +import { AzureDevOpsApi } from './AzureDevOpsApi'; +/** @public */ export class AzureDevOpsClient implements AzureDevOpsApi { private readonly discoveryApi: DiscoveryApi; private readonly identityApi: IdentityApi; @@ -130,6 +132,14 @@ export class AzureDevOpsClient implements AzureDevOpsApi { return { items }; } + public async getReadme(opts: ReadmeConfig): Promise { + return await this.get( + `readme/${encodeURIComponent(opts.project)}/${encodeURIComponent( + opts.repo, + )}`, + ); + } + private async get(path: string): Promise { const baseUrl = `${await this.discoveryApi.getBaseUrl('azure-devops')}/`; const url = new URL(path, baseUrl); diff --git a/plugins/azure-devops/src/components/AzurePullRequestsIcon/AzurePullRequestsIcon.tsx b/plugins/azure-devops/src/components/AzurePullRequestsIcon/AzurePullRequestsIcon.tsx index bb4cb8c081..99e3f74e90 100644 --- a/plugins/azure-devops/src/components/AzurePullRequestsIcon/AzurePullRequestsIcon.tsx +++ b/plugins/azure-devops/src/components/AzurePullRequestsIcon/AzurePullRequestsIcon.tsx @@ -14,10 +14,10 @@ * limitations under the License. */ +import React from 'react'; import { SvgIcon, SvgIconProps } from '@material-ui/core'; -import React from 'react'; - +/** @public */ export const AzurePullRequestsIcon = (props: SvgIconProps) => ( { +export const EntityPageAzurePipelines = (props: { defaultLimit?: number }) => { const { entity } = useEntity(); const { project, repo, definition } = getAnnotationFromEntity(entity); const { items, loading, error } = useBuildRuns( project, - defaultLimit, + props.defaultLimit, repo, definition, ); diff --git a/plugins/azure-devops/src/components/EntityPageAzurePullRequests/EntityPageAzurePullRequests.tsx b/plugins/azure-devops/src/components/EntityPageAzurePullRequests/EntityPageAzurePullRequests.tsx index 3d1a3ef77a..b5a21ff750 100644 --- a/plugins/azure-devops/src/components/EntityPageAzurePullRequests/EntityPageAzurePullRequests.tsx +++ b/plugins/azure-devops/src/components/EntityPageAzurePullRequests/EntityPageAzurePullRequests.tsx @@ -17,10 +17,8 @@ import { PullRequestTable } from '../PullRequestTable/PullRequestTable'; import React from 'react'; -export const EntityPageAzurePullRequests = ({ - defaultLimit, -}: { +export const EntityPageAzurePullRequests = (props: { defaultLimit?: number; }) => { - return ; + return ; }; diff --git a/plugins/azure-devops/src/components/PullRequestsPage/PullRequestsPage.tsx b/plugins/azure-devops/src/components/PullRequestsPage/PullRequestsPage.tsx index 158c4bca5b..c5da207bd6 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/PullRequestsPage.tsx +++ b/plugins/azure-devops/src/components/PullRequestsPage/PullRequestsPage.tsx @@ -24,7 +24,6 @@ import { import { PullRequestColumnConfig, PullRequestGroup } from './lib/types'; import React, { useState } from 'react'; import { getPullRequestGroupConfigs, getPullRequestGroups } from './lib/utils'; - import { FilterType } from './lib/filters'; import { PullRequestGrid } from './lib/PullRequestGrid'; import { useDashboardPullRequests } from '../../hooks'; @@ -71,11 +70,9 @@ type PullRequestsPageProps = { defaultColumnConfigs?: PullRequestColumnConfig[]; }; -export const PullRequestsPage = ({ - projectName, - pollingInterval, - defaultColumnConfigs, -}: PullRequestsPageProps) => { +export const PullRequestsPage = (props: PullRequestsPageProps) => { + const { projectName, pollingInterval, defaultColumnConfigs } = props; + const { pullRequests, loading, error } = useDashboardPullRequests( projectName, pollingInterval, diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/allFilter.ts b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/allFilter.ts index 90ec822ef6..952f7ddc57 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/allFilter.ts +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/allFilter.ts @@ -18,6 +18,7 @@ import { BaseFilter, FilterType, PullRequestFilter } from './types'; import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common'; +/** @public */ export type AllFilter = BaseFilter & { type: FilterType.All; }; diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToTeamFilter.ts b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToTeamFilter.ts index 8e816db2c3..fa6b3de00a 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToTeamFilter.ts +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToTeamFilter.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { BaseFilter, FilterType, PullRequestFilter } from './types'; - import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common'; +import { BaseFilter, FilterType, PullRequestFilter } from './types'; import { stringArrayHas } from '../../../../utils'; +/** @public */ export type AssignedToTeamFilter = BaseFilter & { type: FilterType.AssignedToTeam; teamId: string; diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToTeamsFilter.ts b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToTeamsFilter.ts index ce5e5bcc11..df93e38f81 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToTeamsFilter.ts +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToTeamsFilter.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { BaseFilter, FilterType, PullRequestFilter } from './types'; - import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common'; +import { BaseFilter, FilterType, PullRequestFilter } from './types'; import { createAssignedToTeamFilter } from './assignedToTeamFilter'; +/** @public */ export type AssignedToTeamsFilter = BaseFilter & ( | { diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToUserFilter.ts b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToUserFilter.ts index 95ee3d5a59..3f554de62b 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToUserFilter.ts +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/assignedToUserFilter.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { BaseFilter, FilterType, PullRequestFilter } from './types'; - import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common'; +import { BaseFilter, FilterType, PullRequestFilter } from './types'; import { stringArrayHas } from '../../../../utils'; +/** @public */ export type AssignedToUserFilter = BaseFilter & ( | { diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByTeamFilter.ts b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByTeamFilter.ts index 70a388b540..e4d28d28b1 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByTeamFilter.ts +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByTeamFilter.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { BaseFilter, FilterType, PullRequestFilter } from './types'; - import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common'; +import { BaseFilter, FilterType, PullRequestFilter } from './types'; import { stringArrayHas } from '../../../../utils'; +/** @public */ export type CreatedByTeamFilter = BaseFilter & ({ type: FilterType.CreatedByTeam; diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByTeamsFilter.ts b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByTeamsFilter.ts index 34ed81db5d..44e02136ec 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByTeamsFilter.ts +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByTeamsFilter.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { BaseFilter, FilterType, PullRequestFilter } from './types'; - import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common'; +import { BaseFilter, FilterType, PullRequestFilter } from './types'; import { createCreatedByTeamFilter } from './createdByTeamFilter'; +/** @public */ export type CreatedByTeamsFilter = BaseFilter & ( | ({ diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByUserFilter.ts b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByUserFilter.ts index 69d4f23db5..24c14311eb 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByUserFilter.ts +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/createdByUserFilter.ts @@ -14,11 +14,11 @@ * limitations under the License. */ -import { BaseFilter, FilterType, PullRequestFilter } from './types'; - import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common'; +import { BaseFilter, FilterType, PullRequestFilter } from './types'; import { equalsIgnoreCase } from '../../../../utils'; +/** @public */ export type CreatedByUserFilter = BaseFilter & ( | { diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/types.ts b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/types.ts index bc4643d51b..6b0d95eb78 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/types.ts +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/filters/types.ts @@ -23,6 +23,7 @@ import { CreatedByTeamsFilter } from './createdByTeamsFilter'; import { CreatedByUserFilter } from './createdByUserFilter'; import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common'; +/** @public */ export enum FilterType { All = 'All', @@ -41,6 +42,7 @@ export enum FilterType { CreatedByCurrentUsersTeams = 'CreatedByCurrentUsersTeams', } +/** @public */ export const FilterTypes = [ FilterType.All, @@ -57,10 +59,12 @@ export const FilterTypes = [ FilterType.CreatedByCurrentUsersTeams, ] as const; +/** @public */ export type BaseFilter = { type: FilterType; }; +/** @public */ export type Filter = | AssignedToUserFilter | CreatedByUserFilter @@ -80,4 +84,5 @@ export type { AllFilter, }; +/** @public */ export type PullRequestFilter = (pullRequest: DashboardPullRequest) => boolean; diff --git a/plugins/azure-devops/src/components/PullRequestsPage/lib/types.ts b/plugins/azure-devops/src/components/PullRequestsPage/lib/types.ts index 74c8ebe605..5f5f0119d8 100644 --- a/plugins/azure-devops/src/components/PullRequestsPage/lib/types.ts +++ b/plugins/azure-devops/src/components/PullRequestsPage/lib/types.ts @@ -14,22 +14,24 @@ * limitations under the License. */ +import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common'; import { Filter, PullRequestFilter } from './filters'; -import { DashboardPullRequest } from '@backstage/plugin-azure-devops-common'; - +/** @public */ export interface PullRequestColumnConfig { title: string; filters: Filter[]; simplified?: boolean; } +/** @public */ export interface PullRequestGroupConfig { title: string; filter: PullRequestFilter; simplified?: boolean; } +/** @public */ export interface PullRequestGroup { title: string; pullRequests: DashboardPullRequest[]; diff --git a/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx b/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx new file mode 100644 index 0000000000..d06726e929 --- /dev/null +++ b/plugins/azure-devops/src/components/ReadmeCard/ReadmeCard.tsx @@ -0,0 +1,120 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Box, Button, makeStyles } from '@material-ui/core'; +import { + InfoCard, + Progress, + MarkdownContent, + EmptyState, + ErrorPanel, +} from '@backstage/core-components'; +import { useEntity } from '@backstage/plugin-catalog-react'; +import { useProjectRepoFromEntity } from '../../hooks'; +import { useApi } from '@backstage/core-plugin-api'; +import React from 'react'; +import { azureDevOpsApiRef } from '../../api'; +import useAsync from 'react-use/lib/useAsync'; + +const useStyles = makeStyles(theme => ({ + readMe: { + overflowY: 'auto', + paddingRight: theme.spacing(1), + '&::-webkit-scrollbar-track': { + backgroundColor: '#F5F5F5', + borderRadius: '5px', + }, + '&::-webkit-scrollbar': { + width: '5px', + backgroundColor: '#F5F5F5', + borderRadius: '5px', + }, + '&::-webkit-scrollbar-thumb': { + border: '1px solid #555555', + backgroundColor: '#555', + borderRadius: '4px', + }, + }, +})); + +type Props = { + maxHeight?: number; +}; + +type ErrorProps = { + error: Error; +}; + +function isNotFoundError(error: any): boolean { + return error?.response?.status === 404; +} + +const ReadmeCardError = ({ error }: ErrorProps) => { + if (isNotFoundError(error)) + return ( + + Read more + + } + /> + ); + return ; +}; + +export const ReadmeCard = (props: Props) => { + const classes = useStyles(); + const api = useApi(azureDevOpsApiRef); + const { entity } = useEntity(); + const { project, repo } = useProjectRepoFromEntity(entity); + + const { loading, error, value } = useAsync( + () => + api.getReadme({ + project, + repo, + }), + [api, project, repo, entity], + ); + + if (loading) { + return ; + } else if (error) { + return ; + } + + return ( + + + + + + ); +}; diff --git a/plugins/search/src/components/SearchResultPager/index.ts b/plugins/azure-devops/src/components/ReadmeCard/index.ts similarity index 85% rename from plugins/search/src/components/SearchResultPager/index.ts rename to plugins/azure-devops/src/components/ReadmeCard/index.ts index 39b72ec71f..9b92a0eaf1 100644 --- a/plugins/search/src/components/SearchResultPager/index.ts +++ b/plugins/azure-devops/src/components/ReadmeCard/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * Copyright 2022 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,4 +14,4 @@ * limitations under the License. */ -export { SearchResultPager } from './SearchResultPager'; +export { ReadmeCard } from './ReadmeCard'; diff --git a/plugins/azure-devops/src/index.ts b/plugins/azure-devops/src/index.ts index e65c1d02a3..37e85b7422 100644 --- a/plugins/azure-devops/src/index.ts +++ b/plugins/azure-devops/src/index.ts @@ -19,6 +19,7 @@ export { EntityAzurePipelinesContent, EntityAzureGitTagsContent, EntityAzurePullRequestsContent, + EntityAzureReadmeCard, isAzureDevOpsAvailable, isAzurePipelinesAvailable, AzurePullRequestsPage, diff --git a/plugins/azure-devops/src/plugin.ts b/plugins/azure-devops/src/plugin.ts index ccd183eee9..4dd423f35a 100644 --- a/plugins/azure-devops/src/plugin.ts +++ b/plugins/azure-devops/src/plugin.ts @@ -29,6 +29,7 @@ import { createApiFactory, createPlugin, createRoutableExtension, + createComponentExtension, discoveryApiRef, identityApiRef, } from '@backstage/core-plugin-api'; @@ -37,9 +38,11 @@ import { AzureDevOpsClient } from './api/AzureDevOpsClient'; import { Entity } from '@backstage/catalog-model'; import { azureDevOpsApiRef } from './api/AzureDevOpsApi'; +/** @public */ export const isAzureDevOpsAvailable = (entity: Entity) => Boolean(entity.metadata.annotations?.[AZURE_DEVOPS_REPO_ANNOTATION]); +/** @public */ export const isAzurePipelinesAvailable = (entity: Entity) => Boolean(entity.metadata.annotations?.[AZURE_DEVOPS_REPO_ANNOTATION]) || (Boolean(entity.metadata.annotations?.[AZURE_DEVOPS_PROJECT_ANNOTATION]) && @@ -47,6 +50,7 @@ export const isAzurePipelinesAvailable = (entity: Entity) => entity.metadata.annotations?.[AZURE_DEVOPS_BUILD_DEFINITION_ANNOTATION], )); +/** @public */ export const azureDevOpsPlugin = createPlugin({ id: 'azureDevOps', apis: [ @@ -59,6 +63,7 @@ export const azureDevOpsPlugin = createPlugin({ ], }); +/** @public */ export const AzurePullRequestsPage = azureDevOpsPlugin.provide( createRoutableExtension({ name: 'AzurePullRequestsPage', @@ -68,6 +73,7 @@ export const AzurePullRequestsPage = azureDevOpsPlugin.provide( }), ); +/** @public */ export const EntityAzurePipelinesContent = azureDevOpsPlugin.provide( createRoutableExtension({ name: 'EntityAzurePipelinesContent', @@ -79,6 +85,7 @@ export const EntityAzurePipelinesContent = azureDevOpsPlugin.provide( }), ); +/** @public */ export const EntityAzureGitTagsContent = azureDevOpsPlugin.provide( createRoutableExtension({ name: 'EntityAzureGitTagsContent', @@ -90,6 +97,7 @@ export const EntityAzureGitTagsContent = azureDevOpsPlugin.provide( }), ); +/** @public */ export const EntityAzurePullRequestsContent = azureDevOpsPlugin.provide( createRoutableExtension({ name: 'EntityAzurePullRequestsContent', @@ -100,3 +108,13 @@ export const EntityAzurePullRequestsContent = azureDevOpsPlugin.provide( mountPoint: azurePullRequestsEntityContentRouteRef, }), ); + +/** @public */ +export const EntityAzureReadmeCard = azureDevOpsPlugin.provide( + createComponentExtension({ + name: 'EntityAzureReadmeCard', + component: { + lazy: () => import('./components/ReadmeCard').then(m => m.ReadmeCard), + }, + }), +); diff --git a/plugins/badges-backend/CHANGELOG.md b/plugins/badges-backend/CHANGELOG.md index 779625184e..c9730194af 100644 --- a/plugins/badges-backend/CHANGELOG.md +++ b/plugins/badges-backend/CHANGELOG.md @@ -1,5 +1,30 @@ # @backstage/plugin-badges-backend +## 0.1.29 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## 0.1.29-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + +## 0.1.28 + +### Patch Changes + +- 58fd5ee9d5: Add missing installation instructions +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/catalog-client@1.0.4 + - @backstage/errors@1.1.0 + ## 0.1.28-next.2 ### Patch Changes diff --git a/plugins/badges-backend/api-report.md b/plugins/badges-backend/api-report.md index 0660d23fdb..0ecf41ee85 100644 --- a/plugins/badges-backend/api-report.md +++ b/plugins/badges-backend/api-report.md @@ -9,8 +9,6 @@ import { Entity } from '@backstage/catalog-model'; import express from 'express'; import { PluginEndpointDiscovery } from '@backstage/backend-common'; -// Warning: (ae-missing-release-tag) "Badge" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface Badge { color?: string; @@ -23,8 +21,6 @@ export interface Badge { style?: BadgeStyle; } -// Warning: (ae-missing-release-tag) "BADGE_STYLES" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const BADGE_STYLES: readonly [ 'plastic', @@ -34,8 +30,6 @@ export const BADGE_STYLES: readonly [ 'social', ]; -// Warning: (ae-missing-release-tag) "BadgeBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type BadgeBuilder = { getBadges(): Promise; @@ -43,8 +37,6 @@ export type BadgeBuilder = { createBadgeSvg(options: BadgeOptions): Promise; }; -// Warning: (ae-missing-release-tag) "BadgeContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface BadgeContext { // (undocumented) @@ -55,39 +47,29 @@ export interface BadgeContext { entity?: Entity; } -// Warning: (ae-missing-release-tag) "BadgeFactories" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface BadgeFactories { // (undocumented) [id: string]: BadgeFactory; } -// Warning: (ae-missing-release-tag) "BadgeFactory" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface BadgeFactory { // (undocumented) createBadge(context: BadgeContext): Badge; } -// Warning: (ae-missing-release-tag) "BadgeInfo" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type BadgeInfo = { id: string; }; -// Warning: (ae-missing-release-tag) "BadgeOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type BadgeOptions = { badgeInfo: BadgeInfo; context: BadgeContext; }; -// Warning: (ae-missing-release-tag) "BadgeSpec" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type BadgeSpec = { id: string; @@ -96,23 +78,15 @@ export type BadgeSpec = { markdown: string; }; -// Warning: (ae-missing-release-tag) "BadgeStyle" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type BadgeStyle = typeof BADGE_STYLES[number]; -// Warning: (ae-missing-release-tag) "createDefaultBadgeFactories" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const createDefaultBadgeFactories: () => BadgeFactories; -// Warning: (ae-missing-release-tag) "createRouter" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export function createRouter(options: RouterOptions): Promise; -// Warning: (ae-missing-release-tag) "DefaultBadgeBuilder" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class DefaultBadgeBuilder implements BadgeBuilder { constructor(factories: BadgeFactories); @@ -126,8 +100,6 @@ export class DefaultBadgeBuilder implements BadgeBuilder { protected getMarkdownCode(params: Badge, badgeUrl: string): string; } -// Warning: (ae-missing-release-tag) "RouterOptions" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface RouterOptions { // (undocumented) diff --git a/plugins/badges-backend/package.json b/plugins/badges-backend/package.json index 1e0bc62b15..e642121802 100644 --- a/plugins/badges-backend/package.json +++ b/plugins/badges-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges-backend", "description": "A Backstage backend plugin that generates README badges for your entities", - "version": "0.1.28-next.2", + "version": "0.1.29", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,11 +34,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.2", - "@backstage/catalog-client": "^1.0.4-next.1", - "@backstage/catalog-model": "^1.1.0-next.2", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", + "@backstage/errors": "^1.1.0", "@types/express": "^4.17.6", "badge-maker": "^3.3.0", "cors": "^2.8.5", @@ -48,7 +48,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.2", + "@backstage/cli": "^0.18.1", "@types/supertest": "^2.0.8", "supertest": "^6.1.3" }, diff --git a/plugins/badges-backend/src/badges.ts b/plugins/badges-backend/src/badges.ts index 78108de080..9167116d95 100644 --- a/plugins/badges-backend/src/badges.ts +++ b/plugins/badges-backend/src/badges.ts @@ -31,6 +31,7 @@ function entityUrl(context: BadgeContext): string { return `${catalogUrl}/${entityUri}`.toLowerCase(); } +/** @public */ export const createDefaultBadgeFactories = (): BadgeFactories => ({ pingback: { createBadge: (context: BadgeContext): Badge => { diff --git a/plugins/badges-backend/src/lib/BadgeBuilder/DefaultBadgeBuilder.ts b/plugins/badges-backend/src/lib/BadgeBuilder/DefaultBadgeBuilder.ts index 78e34351a0..efe58078f7 100644 --- a/plugins/badges-backend/src/lib/BadgeBuilder/DefaultBadgeBuilder.ts +++ b/plugins/badges-backend/src/lib/BadgeBuilder/DefaultBadgeBuilder.ts @@ -19,6 +19,7 @@ import { makeBadge, Format } from 'badge-maker'; import { BadgeBuilder, BadgeInfo, BadgeOptions, BadgeSpec } from './types'; import { Badge, BadgeFactories } from '../../types'; +/** @public */ export class DefaultBadgeBuilder implements BadgeBuilder { constructor(private readonly factories: BadgeFactories) {} diff --git a/plugins/badges-backend/src/lib/BadgeBuilder/types.ts b/plugins/badges-backend/src/lib/BadgeBuilder/types.ts index e2be17a7db..fa1dd4a5ad 100644 --- a/plugins/badges-backend/src/lib/BadgeBuilder/types.ts +++ b/plugins/badges-backend/src/lib/BadgeBuilder/types.ts @@ -16,15 +16,18 @@ import { Badge, BadgeContext } from '../../types'; +/** @public */ export type BadgeInfo = { id: string; }; +/** @public */ export type BadgeOptions = { badgeInfo: BadgeInfo; context: BadgeContext; }; +/** @public */ export type BadgeSpec = { /** Badge id */ id: string; @@ -39,6 +42,7 @@ export type BadgeSpec = { markdown: string; }; +/** @public */ export type BadgeBuilder = { getBadges(): Promise; createBadgeJson(options: BadgeOptions): Promise; diff --git a/plugins/badges-backend/src/service/router.ts b/plugins/badges-backend/src/service/router.ts index b7211a0aad..2006b45dc4 100644 --- a/plugins/badges-backend/src/service/router.ts +++ b/plugins/badges-backend/src/service/router.ts @@ -26,6 +26,7 @@ import { NotFoundError } from '@backstage/errors'; import { BadgeBuilder, DefaultBadgeBuilder } from '../lib/BadgeBuilder'; import { BadgeContext, BadgeFactories } from '../types'; +/** @public */ export interface RouterOptions { badgeBuilder?: BadgeBuilder; badgeFactories?: BadgeFactories; @@ -34,6 +35,7 @@ export interface RouterOptions { discovery: PluginEndpointDiscovery; } +/** @public */ export async function createRouter( options: RouterOptions, ): Promise { diff --git a/plugins/badges-backend/src/types.ts b/plugins/badges-backend/src/types.ts index 0467b18155..eec7063f88 100644 --- a/plugins/badges-backend/src/types.ts +++ b/plugins/badges-backend/src/types.ts @@ -17,6 +17,7 @@ import { Config } from '@backstage/config'; import { Entity } from '@backstage/catalog-model'; +/** @public */ export const BADGE_STYLES = [ 'plastic', 'flat', @@ -24,8 +25,11 @@ export const BADGE_STYLES = [ 'for-the-badge', 'social', ] as const; + +/** @public */ export type BadgeStyle = typeof BADGE_STYLES[number]; +/** @public */ export interface Badge { /** Badge message background color. */ color?: string; @@ -48,16 +52,19 @@ export interface Badge { style?: BadgeStyle; } +/** @public */ export interface BadgeContext { badgeUrl: string; config: Config; entity?: Entity; // for entity badges } +/** @public */ export interface BadgeFactory { createBadge(context: BadgeContext): Badge; } +/** @public */ export interface BadgeFactories { [id: string]: BadgeFactory; } diff --git a/plugins/badges/CHANGELOG.md b/plugins/badges/CHANGELOG.md index acfbcd6e0a..534c433781 100644 --- a/plugins/badges/CHANGELOG.md +++ b/plugins/badges/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-badges +## 0.2.32 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.2.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.2.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.2.31 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.2.31-next.3 ### Patch Changes diff --git a/plugins/badges/api-report.md b/plugins/badges/api-report.md index f4ba97cabc..b051bbb452 100644 --- a/plugins/badges/api-report.md +++ b/plugins/badges/api-report.md @@ -7,18 +7,11 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; -// Warning: (ae-missing-release-tag) "badgesPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const badgesPlugin: BackstagePlugin<{}, {}>; +export const badgesPlugin: BackstagePlugin<{}, {}, {}>; -// Warning: (ae-missing-release-tag) "EntityBadgesDialog" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityBadgesDialog: ({ - open, - onClose, -}: { +export const EntityBadgesDialog: (props: { open: boolean; onClose?: (() => any) | undefined; }) => JSX.Element; diff --git a/plugins/badges/package.json b/plugins/badges/package.json index 7c73b55f9e..522b860c47 100644 --- a/plugins/badges/package.json +++ b/plugins/badges/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-badges", "description": "A Backstage plugin that generates README badges for your entities", - "version": "0.2.31-next.3", + "version": "0.2.32", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,12 +30,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -46,17 +46,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/badges/src/components/EntityBadgesDialog.tsx b/plugins/badges/src/components/EntityBadgesDialog.tsx index 422dbc96a3..097bba5581 100644 --- a/plugins/badges/src/components/EntityBadgesDialog.tsx +++ b/plugins/badges/src/components/EntityBadgesDialog.tsx @@ -37,12 +37,11 @@ import { } from '@backstage/core-components'; import { useApi } from '@backstage/core-plugin-api'; -type Props = { +export const EntityBadgesDialog = (props: { open: boolean; onClose?: () => any; -}; - -export const EntityBadgesDialog = ({ open, onClose }: Props) => { +}) => { + const { open, onClose } = props; const theme = useTheme(); const { entity } = useAsyncEntity(); const fullScreen = useMediaQuery(theme.breakpoints.down('sm')); diff --git a/plugins/badges/src/plugin.ts b/plugins/badges/src/plugin.ts index ee88fb31e0..7ef3025458 100644 --- a/plugins/badges/src/plugin.ts +++ b/plugins/badges/src/plugin.ts @@ -22,6 +22,7 @@ import { identityApiRef, } from '@backstage/core-plugin-api'; +/** @public */ export const badgesPlugin = createPlugin({ id: 'badges', apis: [ @@ -34,6 +35,7 @@ export const badgesPlugin = createPlugin({ ], }); +/** @public */ export const EntityBadgesDialog = badgesPlugin.provide( createComponentExtension({ name: 'EntityBadgesDialog', diff --git a/plugins/bazaar-backend/CHANGELOG.md b/plugins/bazaar-backend/CHANGELOG.md index 81358cfc7f..d607584548 100644 --- a/plugins/bazaar-backend/CHANGELOG.md +++ b/plugins/bazaar-backend/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-bazaar-backend +## 0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-test-utils@0.1.27 + +## 0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-test-utils@0.1.27-next.0 + +## 0.1.18 + +### Patch Changes + +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- 77abf50acf: Fixed api warnings +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/backend-test-utils@0.1.26 + ## 0.1.18-next.1 ### Patch Changes diff --git a/plugins/bazaar-backend/package.json b/plugins/bazaar-backend/package.json index 351535e544..85539c6dab 100644 --- a/plugins/bazaar-backend/package.json +++ b/plugins/bazaar-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar-backend", - "version": "0.1.18-next.1", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,8 +23,8 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.2", - "@backstage/backend-test-utils": "^0.1.26-next.2", + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-test-utils": "^0.1.27", "@backstage/config": "^1.0.1", "@types/express": "^4.17.6", "express": "^4.17.1", @@ -34,7 +34,7 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.2" + "@backstage/cli": "^0.18.1" }, "files": [ "dist", diff --git a/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts b/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts index 3099e5bbb2..e1a722016b 100644 --- a/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts +++ b/plugins/bazaar-backend/src/service/DatabaseHandler.test.ts @@ -16,6 +16,7 @@ import { DatabaseHandler } from './DatabaseHandler'; import { TestDatabaseId, TestDatabases } from '@backstage/backend-test-utils'; +import { Knex as KnexType } from 'knex'; const bazaarProject: any = { name: 'n1', @@ -35,11 +36,24 @@ describe('DatabaseHandler', () => { ids: ['POSTGRES_13', 'POSTGRES_9', 'SQLITE_3'], }); + function createDatabaseManager( + client: KnexType, + skipMigrations: boolean = false, + ) { + return { + getClient: async () => client, + migrations: { + skip: skipMigrations, + }, + }; + } + async function createDatabaseHandler(databaseId: TestDatabaseId) { const knex = await databases.init(databaseId); + const databaseManager = createDatabaseManager(knex); return { knex, - dbHandler: await DatabaseHandler.create({ database: knex }), + dbHandler: await DatabaseHandler.create({ database: databaseManager }), }; } diff --git a/plugins/bazaar-backend/src/service/DatabaseHandler.ts b/plugins/bazaar-backend/src/service/DatabaseHandler.ts index 7da06a54b8..d8d975b7ed 100644 --- a/plugins/bazaar-backend/src/service/DatabaseHandler.ts +++ b/plugins/bazaar-backend/src/service/DatabaseHandler.ts @@ -14,7 +14,10 @@ * limitations under the License. */ -import { resolvePackagePath } from '@backstage/backend-common'; +import { + PluginDatabaseManager, + resolvePackagePath, +} from '@backstage/backend-common'; import { Knex } from 'knex'; const migrationsDir = resolvePackagePath( @@ -23,24 +26,27 @@ const migrationsDir = resolvePackagePath( ); type Options = { - database: Knex; + database: PluginDatabaseManager; }; export class DatabaseHandler { static async create(options: Options): Promise { const { database } = options; + const client = await database.getClient(); - await database.migrate.latest({ - directory: migrationsDir, - }); + if (!database.migrations?.skip) { + await client.migrate.latest({ + directory: migrationsDir, + }); + } - return new DatabaseHandler(options); + return new DatabaseHandler(client); } - private readonly database: Knex; + private readonly client: Knex; - private constructor(options: Options) { - this.database = options.database; + private constructor(client: Knex) { + this.client = client; } private columns = [ @@ -58,14 +64,11 @@ export class DatabaseHandler { ]; async getMembers(id: string) { - return await this.database - .select('*') - .from('members') - .where({ item_id: id }); + return await this.client.select('*').from('members').where({ item_id: id }); } async addMember(id: number, userId: string, picture?: string) { - await this.database + await this.client .insert({ item_id: id, user_id: userId, @@ -75,18 +78,18 @@ export class DatabaseHandler { } async deleteMember(id: number, userId: string) { - return await this.database('members') + return await this.client('members') .where({ item_id: id }) .andWhere('user_id', userId) .del(); } async getMetadataById(id: number) { - const coalesce = this.database.raw( + const coalesce = this.client.raw( 'coalesce(count(members.item_id), 0) as members_count', ); - return await this.database('metadata') + return await this.client('metadata') .select([...this.columns, coalesce]) .where({ 'metadata.id': id }) .groupBy(this.columns) @@ -94,11 +97,11 @@ export class DatabaseHandler { } async getMetadataByRef(entityRef: string) { - const coalesce = this.database.raw( + const coalesce = this.client.raw( 'coalesce(count(members.item_id), 0) as members_count', ); - return await this.database('metadata') + return await this.client('metadata') .select([...this.columns, coalesce]) .where({ 'metadata.entity_ref': entityRef }) .groupBy(this.columns) @@ -118,7 +121,7 @@ export class DatabaseHandler { responsible, } = bazaarProject; - await this.database + await this.client .insert({ name, entity_ref: entityRef, @@ -148,7 +151,7 @@ export class DatabaseHandler { responsible, } = bazaarProject; - return await this.database('metadata').where({ id: id }).update({ + return await this.client('metadata').where({ id: id }).update({ name, entity_ref: entityRef, description, @@ -163,15 +166,15 @@ export class DatabaseHandler { } async deleteMetadata(id: number) { - return await this.database('metadata').where({ id: id }).del(); + return await this.client('metadata').where({ id: id }).del(); } async getProjects() { - const coalesce = this.database.raw( + const coalesce = this.client.raw( 'coalesce(count(members.item_id), 0) as members_count', ); - return await this.database('metadata') + return await this.client('metadata') .select([...this.columns, coalesce]) .groupBy(this.columns) .leftJoin('members', 'metadata.id', '=', 'members.item_id'); diff --git a/plugins/bazaar-backend/src/service/router.ts b/plugins/bazaar-backend/src/service/router.ts index c61309d279..a5248c2949 100644 --- a/plugins/bazaar-backend/src/service/router.ts +++ b/plugins/bazaar-backend/src/service/router.ts @@ -33,9 +33,8 @@ export async function createRouter( options: RouterOptions, ): Promise { const { logger, database } = options; - const db = await database.getClient(); - const dbHandler = await DatabaseHandler.create({ database: db }); + const dbHandler = await DatabaseHandler.create({ database }); logger.info('Initializing Bazaar backend'); diff --git a/plugins/bazaar/CHANGELOG.md b/plugins/bazaar/CHANGELOG.md index 48d5f8a85a..c1c9f91eed 100644 --- a/plugins/bazaar/CHANGELOG.md +++ b/plugins/bazaar/CHANGELOG.md @@ -1,5 +1,52 @@ # @backstage/plugin-bazaar +## 0.1.23 + +### Patch Changes + +- Updated dependencies + - @backstage/cli@0.18.1 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog@1.5.0 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.1.23-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/cli@0.18.1-next.1 + - @backstage/core-components@0.11.0-next.2 + - @backstage/plugin-catalog@1.5.0-next.2 + +## 0.1.23-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog@1.5.0-next.0 + - @backstage/cli@0.18.1-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.22 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 77abf50acf: Fixed api warnings +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-catalog@1.4.0 + - @backstage/cli@0.18.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + ## 0.1.22-next.3 ### Patch Changes diff --git a/plugins/bazaar/api-report.md b/plugins/bazaar/api-report.md index d711df7320..c6afde73f2 100644 --- a/plugins/bazaar/api-report.md +++ b/plugins/bazaar/api-report.md @@ -16,6 +16,7 @@ export const bazaarPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; diff --git a/plugins/bazaar/package.json b/plugins/bazaar/package.json index 371596b981..db2b72f920 100644 --- a/plugins/bazaar/package.json +++ b/plugins/bazaar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-bazaar", - "version": "0.1.22-next.3", + "version": "0.1.23", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,13 +24,13 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog": "^1.4.0-next.3", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", + "@backstage/cli": "^0.18.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog": "^1.5.0", + "@backstage/plugin-catalog-react": "^1.1.3", "@date-io/luxon": "1.x", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -47,8 +47,8 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/dev-utils": "^1.0.4-next.3", + "@backstage/cli": "^0.18.1", + "@backstage/dev-utils": "^1.0.5", "@testing-library/jest-dom": "^5.10.1", "cross-fetch": "^3.1.5" }, diff --git a/plugins/bitbucket-cloud-common/CHANGELOG.md b/plugins/bitbucket-cloud-common/CHANGELOG.md index c92c9e7d08..e6c2f366d6 100644 --- a/plugins/bitbucket-cloud-common/CHANGELOG.md +++ b/plugins/bitbucket-cloud-common/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-bitbucket-cloud-common +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + +## 0.1.1 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/integration@1.2.2 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/bitbucket-cloud-common/package.json b/plugins/bitbucket-cloud-common/package.json index e196bd1837..c2c8534013 100644 --- a/plugins/bitbucket-cloud-common/package.json +++ b/plugins/bitbucket-cloud-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitbucket-cloud-common", "description": "Common functionalities for bitbucket-cloud plugins", - "version": "0.1.1-next.1", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,13 +28,13 @@ "update-models": "yarn refresh-schema && yarn generate-models && yarn reduce-models" }, "dependencies": { - "@backstage/integration": "^1.2.2-next.3", + "@backstage/integration": "^1.3.0", "cross-fetch": "^3.1.5" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@openapitools/openapi-generator-cli": "^2.4.26", - "msw": "^0.44.0", + "msw": "^0.45.0", "ts-morph": "^15.0.0" }, "files": [ diff --git a/plugins/bitrise/CHANGELOG.md b/plugins/bitrise/CHANGELOG.md index ec83a0c66e..8fd4113dd2 100644 --- a/plugins/bitrise/CHANGELOG.md +++ b/plugins/bitrise/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-bitrise +## 0.1.35 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.1.35-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.1.35-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.34 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.1.34-next.3 ### Patch Changes diff --git a/plugins/bitrise/api-report.md b/plugins/bitrise/api-report.md index 293ea5fe40..f8421a532a 100644 --- a/plugins/bitrise/api-report.md +++ b/plugins/bitrise/api-report.md @@ -11,7 +11,7 @@ import { Entity } from '@backstage/catalog-model'; // Warning: (ae-missing-release-tag) "bitrisePlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const bitrisePlugin: BackstagePlugin<{}, {}>; +export const bitrisePlugin: BackstagePlugin<{}, {}, {}>; // Warning: (ae-missing-release-tag) "EntityBitriseContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // diff --git a/plugins/bitrise/package.json b/plugins/bitrise/package.json index 00cca959d2..7daf3c48fb 100644 --- a/plugins/bitrise/package.json +++ b/plugins/bitrise/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-bitrise", "description": "A Backstage plugin that integrates towards Bitrise", - "version": "0.1.34-next.3", + "version": "0.1.35", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,11 +24,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -43,17 +43,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "@types/recharts": "^1.8.15", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/catalog-backend-module-aws/CHANGELOG.md b/plugins/catalog-backend-module-aws/CHANGELOG.md index a5f6ad1541..ab7ac4b3ac 100644 --- a/plugins/catalog-backend-module-aws/CHANGELOG.md +++ b/plugins/catalog-backend-module-aws/CHANGELOG.md @@ -1,5 +1,49 @@ # @backstage/plugin-catalog-backend-module-aws +## 0.1.8 + +### Patch Changes + +- 17d45dbf10: Deprecate `AwsS3DiscoveryProcessor` in favor of `AwsS3EntityProvider` (since v0.1.4). + + You can find a migration guide at + [the release notes for v0.1.4](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-aws/CHANGELOG.md#014). + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## 0.1.8-next.0 + +### Patch Changes + +- 17d45dbf10: Deprecate `AwsS3DiscoveryProcessor` in favor of `AwsS3EntityProvider` (since v0.1.4). + + You can find a migration guide at + [the release notes for v0.1.4](https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-aws/CHANGELOG.md#014). + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## 0.1.7 + +### Patch Changes + +- f9f1de8100: Add processor for ingesting EKS clusters into the catalog +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + ## 0.1.7-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-aws/api-report.md b/plugins/catalog-backend-module-aws/api-report.md index 4e8db41fac..b1f6358979 100644 --- a/plugins/catalog-backend-module-aws/api-report.md +++ b/plugins/catalog-backend-module-aws/api-report.md @@ -54,7 +54,7 @@ export class AwsOrganizationCloudAccountProcessor implements CatalogProcessor { ): Promise; } -// @public +// @public @deprecated export class AwsS3DiscoveryProcessor implements CatalogProcessor { constructor(reader: UrlReader); // (undocumented) diff --git a/plugins/catalog-backend-module-aws/package.json b/plugins/catalog-backend-module-aws/package.json index 243a4e3a47..5b4eefb70b 100644 --- a/plugins/catalog-backend-module-aws/package.json +++ b/plugins/catalog-backend-module-aws/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-aws", "description": "A Backstage catalog backend module that helps integrate towards AWS", - "version": "0.1.7-next.2", + "version": "0.1.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,13 +33,13 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/backend-tasks": "^0.3.3-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-tasks": "^0.3.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-backend": "^1.3.1", "@backstage/types": "^1.0.0", "aws-sdk": "^2.840.0", "lodash": "^4.17.21", @@ -48,7 +48,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/lodash": "^4.14.151", "aws-sdk-mock": "^5.2.1", "yaml": "^2.0.0" diff --git a/plugins/catalog-backend-module-aws/src/processors/AwsS3DiscoveryProcessor.ts b/plugins/catalog-backend-module-aws/src/processors/AwsS3DiscoveryProcessor.ts index 0390defb2a..84f2289c94 100644 --- a/plugins/catalog-backend-module-aws/src/processors/AwsS3DiscoveryProcessor.ts +++ b/plugins/catalog-backend-module-aws/src/processors/AwsS3DiscoveryProcessor.ts @@ -31,6 +31,7 @@ import limiterFactory from 'p-limit'; * `https://testbucket.s3.us-east-2.amazonaws.com`. * * @public + * @deprecated Use the `AwsS3EntityProvider` instead (see https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-aws/CHANGELOG.md#014). */ export class AwsS3DiscoveryProcessor implements CatalogProcessor { constructor(private readonly reader: UrlReader) {} diff --git a/plugins/catalog-backend-module-azure/CHANGELOG.md b/plugins/catalog-backend-module-azure/CHANGELOG.md index a215ff308e..d7f0d022ce 100644 --- a/plugins/catalog-backend-module-azure/CHANGELOG.md +++ b/plugins/catalog-backend-module-azure/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-catalog-backend-module-azure +## 0.1.6 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## 0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## 0.1.5 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + ## 0.1.5-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-azure/package.json b/plugins/catalog-backend-module-azure/package.json index 059fd5bd27..9cd034bc51 100644 --- a/plugins/catalog-backend-module-azure/package.json +++ b/plugins/catalog-backend-module-azure/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-azure", "description": "A Backstage catalog backend module that helps integrate towards Azure", - "version": "0.1.5-next.2", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,23 +33,23 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/backend-tasks": "^0.3.3-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-model": "^1.1.0", + "@backstage/backend-tasks": "^0.3.4", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-backend": "^1.3.1", "@backstage/types": "^1.0.0", "lodash": "^4.17.21", - "msw": "^0.44.0", + "msw": "^0.45.0", "uuid": "^8.0.0", "node-fetch": "^2.6.7", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "@types/lodash": "^4.14.151" }, "files": [ diff --git a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md index 6bcaf6cc40..2586ee3a5a 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket-cloud/CHANGELOG.md @@ -1,5 +1,37 @@ # @backstage/plugin-catalog-backend-module-bitbucket-cloud +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + - @backstage/plugin-bitbucket-cloud-common@0.1.2 + +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.1.2-next.0 + +## 0.1.1 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/integration@1.2.2 + - @backstage/plugin-bitbucket-cloud-common@0.1.1 + - @backstage/backend-tasks@0.3.3 + ## 0.1.1-next.1 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket-cloud/package.json b/plugins/catalog-backend-module-bitbucket-cloud/package.json index a107959820..83a33bc23d 100644 --- a/plugins/catalog-backend-module-bitbucket-cloud/package.json +++ b/plugins/catalog-backend-module-bitbucket-cloud/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket-cloud", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket Cloud", - "version": "0.1.1-next.1", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,19 +33,19 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-tasks": "^0.3.3-next.3", + "@backstage/backend-tasks": "^0.3.4", "@backstage/config": "^1.0.1", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-bitbucket-cloud-common": "^0.1.1-next.1", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-bitbucket-cloud-common": "^0.1.2", + "@backstage/plugin-catalog-backend": "^1.3.1", "uuid": "^8.0.0", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", - "msw": "^0.44.0" + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/catalog-backend-module-bitbucket-server/.eslintrc.js b/plugins/catalog-backend-module-bitbucket-server/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md new file mode 100644 index 0000000000..216de9ff65 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/CHANGELOG.md @@ -0,0 +1,118 @@ +# @backstage/plugin-catalog-backend-module-bitbucket-server + +## 0.1.0 + +### Minor Changes + +- f7607f9d85: Add new plugin catalog-backend-module-bitbucket-server which adds the `BitbucketServerEntityProvider`. + + The entity provider is meant as a replacement for the `BitbucketDiscoveryProcessor` to be used with Bitbucket Server (Bitbucket Cloud already has a replacement). + + **Before:** + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addProcessor( + BitbucketDiscoveryProcessor.fromConfig(env.config, { logger: env.logger }), + ); + ``` + + ```yaml + # app-config.yaml + catalog: + locations: + - type: bitbucket-discovery + target: 'https://bitbucket.mycompany.com/projects/*/repos/*/catalog-info.yaml + ``` + + **After:** + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addEntityProvider( + BitbucketServerEntityProvider.fromConfig(env.config, { + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + }), + ); + ``` + + ```yaml + # app-config.yaml + catalog: + providers: + bitbucketServer: + yourProviderId: # identifies your ingested dataset + catalogPath: /catalog-info.yaml # default value + filters: # optional + projectKey: '.*' # optional; RegExp + repoSlug: '.*' # optional; RegExp + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## 0.1.0-next.0 + +### Minor Changes + +- f7607f9d85: Add new plugin catalog-backend-module-bitbucket-server which adds the `BitbucketServerEntityProvider`. + + The entity provider is meant as a replacement for the `BitbucketDiscoveryProcessor` to be used with Bitbucket Server (Bitbucket Cloud already has a replacement). + + **Before:** + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addProcessor( + BitbucketDiscoveryProcessor.fromConfig(env.config, { logger: env.logger }), + ); + ``` + + ```yaml + # app-config.yaml + catalog: + locations: + - type: bitbucket-discovery + target: 'https://bitbucket.mycompany.com/projects/*/repos/*/catalog-info.yaml + ``` + + **After:** + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addEntityProvider( + BitbucketServerEntityProvider.fromConfig(env.config, { + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + }), + ); + ``` + + ```yaml + # app-config.yaml + catalog: + providers: + bitbucketServer: + yourProviderId: # identifies your ingested dataset + catalogPath: /catalog-info.yaml # default value + filters: # optional + projectKey: '.*' # optional; RegExp + repoSlug: '.*' # optional; RegExp + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.1-next.2 diff --git a/plugins/catalog-backend-module-bitbucket-server/README.md b/plugins/catalog-backend-module-bitbucket-server/README.md new file mode 100644 index 0000000000..aed8be25ec --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/README.md @@ -0,0 +1,9 @@ +# Catalog Backend Module for Bitbucket Server + +This is an extension module to the catalog-backend plugin, +providing extensions targeted at Bitbucket Server offerings. + +## Getting started + +See [Backstage documentation](https://backstage.io/docs/integrations/bitbucketServer/discovery) +for details on how to install and configure the plugin. diff --git a/plugins/catalog-backend-module-bitbucket-server/api-report.md b/plugins/catalog-backend-module-bitbucket-server/api-report.md new file mode 100644 index 0000000000..1f40f22242 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/api-report.md @@ -0,0 +1,110 @@ +## API Report File for "@backstage/plugin-catalog-backend-module-bitbucket-server" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { BitbucketServerIntegrationConfig } from '@backstage/integration'; +import { Config } from '@backstage/config'; +import { Entity } from '@backstage/catalog-model'; +import { EntityProvider } from '@backstage/plugin-catalog-backend'; +import { EntityProviderConnection } from '@backstage/plugin-catalog-backend'; +import { LocationSpec } from '@backstage/plugin-catalog-backend'; +import { Logger } from 'winston'; +import { TaskRunner } from '@backstage/backend-tasks'; + +// @public +export class BitbucketServerClient { + constructor(options: { config: BitbucketServerIntegrationConfig }); + // (undocumented) + static fromConfig(options: { + config: BitbucketServerIntegrationConfig; + }): BitbucketServerClient; + // (undocumented) + getFile(options: { + projectKey: string; + repo: string; + path: string; + }): Promise; + // (undocumented) + getRepository(options: { + projectKey: string; + repo: string; + }): Promise; + // (undocumented) + listProjects(options: { + listOptions?: BitbucketServerListOptions; + }): Promise>; + // (undocumented) + listRepositories(options: { + projectKey: string; + listOptions?: BitbucketServerListOptions; + }): Promise>; + // (undocumented) + resolvePath(options: { projectKey: string; repo: string; path: string }): { + path: string; + }; +} + +// @public +export class BitbucketServerEntityProvider implements EntityProvider { + // (undocumented) + connect(connection: EntityProviderConnection): Promise; + // (undocumented) + static fromConfig( + config: Config, + options: { + logger: Logger; + schedule: TaskRunner; + parser?: BitbucketServerLocationParser; + }, + ): BitbucketServerEntityProvider[]; + // (undocumented) + getProviderName(): string; + // (undocumented) + refresh(logger: Logger): Promise; +} + +// @public (undocumented) +export type BitbucketServerListOptions = { + [key: string]: number | undefined; + limit?: number | undefined; + start?: number | undefined; +}; + +// @public +export type BitbucketServerLocationParser = (options: { + client: BitbucketServerClient; + location: LocationSpec; + logger: Logger; +}) => AsyncIterable; + +// @public (undocumented) +export type BitbucketServerPagedResponse = { + size: number; + limit: number; + start: number; + isLastPage: boolean; + values: T[]; + nextPageStart: number; +}; + +// @public (undocumented) +export type BitbucketServerProject = { + key: string; +}; + +// @public (undocumented) +export type BitbucketServerRepository = { + project: { + key: string; + }; + slug: string; + description: string; + links: Record< + string, + { + href: string; + }[] + >; +}; +``` diff --git a/plugins/catalog-backend-module-bitbucket-server/config.d.ts b/plugins/catalog-backend-module-bitbucket-server/config.d.ts new file mode 100644 index 0000000000..d8a09c92a4 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/config.d.ts @@ -0,0 +1,80 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export interface Config { + catalog?: { + /** + * List of provider-specific options and attributes + */ + providers?: { + /** + * BitbucketServerEntityProvider configuration + * + * Uses "default" as default id for the single config variant. + */ + bitbucketServer?: + | { + /** + * (Optional) Path to the catalog file. Default to "/catalog-info.yaml". + * @visibility frontend + */ + catalogPath?: string; + /** + * (Optional) Filters applied to discovered catalog files in repositories. + * @visibility frontend + */ + filters?: { + /** + * (Optional) Filter for the repository slug. + * @visibility frontend + */ + repoSlug?: RegExp; + /** + * (Optional) Filter for the project key. + * @visibility frontend + */ + projectKey?: RegExp; + }; + } + | Record< + string, + { + /** + * (Optional) Path to the catalog file. Default to "/catalog-info.yaml". + * @visibility frontend + */ + catalogPath?: string; + /** + * (Optional) Filters applied to discovered catalog files in repositories. + * @visibility frontend + */ + filters?: { + /** + * (Optional) Filter for the repository slug. + * @visibility frontend + */ + repoSlug?: RegExp; + /** + * (Optional) Filter for the project key. + * @visibility frontend + */ + projectKey?: RegExp; + }; + } + >; + }; + }; +} diff --git a/plugins/catalog-backend-module-bitbucket-server/package.json b/plugins/catalog-backend-module-bitbucket-server/package.json new file mode 100644 index 0000000000..d3ffc0a946 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/package.json @@ -0,0 +1,56 @@ +{ + "name": "@backstage/plugin-catalog-backend-module-bitbucket-server", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": false, + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin-module" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-backend-module-bitbucket-server" + }, + "keywords": [ + "backstage" + ], + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-tasks": "^0.3.4", + "@backstage/catalog-model": "^1.0.1", + "@backstage/config": "^1.0.0", + "@backstage/errors": "^1.0.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-backend": "^1.3.1", + "cross-fetch": "^3.1.5", + "uuid": "^8.0.0", + "winston": "^3.2.1" + }, + "devDependencies": { + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", + "msw": "^0.45.0" + }, + "files": [ + "dist", + "config.d.ts" + ], + "configSchema": "config.d.ts" +} diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx b/plugins/catalog-backend-module-bitbucket-server/src/index.ts similarity index 54% rename from plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx rename to plugins/catalog-backend-module-bitbucket-server/src/index.ts index 3db5112b88..34ac3a9966 100644 --- a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.tsx +++ b/plugins/catalog-backend-module-bitbucket-server/src/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * Copyright 2020 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,14 +14,18 @@ * limitations under the License. */ -import { SearchFilterComponentProps } from '@backstage/plugin-search-react'; - /** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. + * A Backstage catalog backend module that helps integrate towards Bitbucket Server + * + * @packageDocumentation */ -export type SearchAutocompleteFilterProps = SearchFilterComponentProps & { - filterSelectedOptions?: boolean; - limitTags?: number; - multiple?: boolean; -}; + +export { BitbucketServerClient } from './lib'; +export type { + BitbucketServerProject, + BitbucketServerRepository, + BitbucketServerPagedResponse, + BitbucketServerListOptions, +} from './lib'; +export { BitbucketServerEntityProvider } from './providers'; +export type { BitbucketServerLocationParser } from './providers'; diff --git a/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts b/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts new file mode 100644 index 0000000000..66ccdc8c9a --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.test.ts @@ -0,0 +1,219 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { BitbucketServerIntegrationConfig } from '@backstage/integration'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { + BitbucketServerClient, + BitbucketServerPagedResponse, + paginated, +} from './BitbucketServerClient'; +import { BitbucketServerProject, BitbucketServerRepository } from './types'; + +const server = setupServer(); + +const catalogInfoFile = ` +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: "backstage" + description: "A Backstage service" +spec: + type: service + lifecycle: experimental + owner: "backstage" +`; + +describe('BitbucketServerClient', () => { + const config: BitbucketServerIntegrationConfig = { + host: 'bitbucket.mycompany.com', + apiBaseUrl: 'https://bitbucket.mycompany.com/api/rest/1.0', + username: 'test-user', + password: 'test-pw', + }; + const client = BitbucketServerClient.fromConfig({ + config: config, + }); + + beforeAll(() => server.listen({ onUnhandledRequest: 'error' })); + afterAll(() => server.close()); + afterEach(() => server.resetHandlers()); + + it('listProjects', async () => { + server.use( + rest.get(`${config.apiBaseUrl}/projects`, (req, res, ctx) => { + if ( + req.headers.get('authorization') !== 'Basic dGVzdC11c2VyOnRlc3QtcHc=' + ) { + return res(ctx.status(400)); + } + const response: BitbucketServerPagedResponse = { + size: 1, + limit: 25, + isLastPage: true, + start: 0, + nextPageStart: 0, + values: [ + { + key: 'test-project', + }, + ], + }; + return res(ctx.json(response)); + }), + ); + + const projects = paginated(options => + client.listProjects({ listOptions: options }), + ); + + const results = []; + for await (const project of projects) { + results.push(project); + } + + expect(results).toHaveLength(1); + expect(results[0].key).toEqual('test-project'); + }); + + it('listRepositories', async () => { + server.use( + rest.get( + `${config.apiBaseUrl}/projects/test-project/repos`, + (req, res, ctx) => { + if ( + req.headers.get('authorization') !== + 'Basic dGVzdC11c2VyOnRlc3QtcHc=' + ) { + return res(ctx.status(400)); + } + const response: BitbucketServerPagedResponse = + { + size: 1, + limit: 25, + isLastPage: true, + start: 0, + nextPageStart: 0, + values: [ + { + project: { + key: 'test-project', + }, + slug: 'test-repository', + description: 'A test repository.', + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/test-project', + }, + ], + }, + }, + ], + }; + return res(ctx.json(response)); + }, + ), + ); + + const repos = paginated(options => + client.listRepositories({ + projectKey: 'test-project', + listOptions: options, + }), + ); + + const results = []; + for await (const repo of repos) { + results.push(repo); + } + + expect(results).toHaveLength(1); + expect(results[0].project.key).toEqual('test-project'); + expect(results[0].slug).toEqual('test-repository'); + expect(results[0].links.self[0].href).toEqual( + 'https://bitbucket.mycompany.com/projects/test-project', + ); + }); + + it('getFile', async () => { + server.use( + rest.get( + `https://${config.host}/projects/test-project/repos/test-repo/raw/catalog-info.yaml`, + (req, res, ctx) => { + if ( + req.headers.get('authorization') !== + 'Basic dGVzdC11c2VyOnRlc3QtcHc=' + ) { + return res(ctx.status(400)); + } + + return res(ctx.text(catalogInfoFile)); + }, + ), + ); + + const response = await client.getFile({ + projectKey: 'test-project', + repo: 'test-repo', + path: 'catalog-info.yaml', + }); + expect(await response.text()).toEqual(catalogInfoFile); + }); + + it('getRepository', async () => { + server.use( + rest.get( + `${config.apiBaseUrl}/projects/test-project/repos/test-repo`, + (req, res, ctx) => { + if ( + req.headers.get('authorization') !== + 'Basic dGVzdC11c2VyOnRlc3QtcHc=' + ) { + return res(ctx.status(400)); + } + const response: BitbucketServerRepository = { + project: { + key: 'test-project', + }, + slug: 'test-repo', + description: 'A test repository.', + links: { + self: [ + { + href: 'https://bitbucket.mycompany.com/projects/test-project', + }, + ], + }, + }; + + return res(ctx.json(response)); + }, + ), + ); + + const repo = await client.getRepository({ + projectKey: 'test-project', + repo: 'test-repo', + }); + expect(repo.project.key).toEqual('test-project'); + expect(repo.slug).toEqual('test-repo'); + expect(repo.links.self[0].href).toEqual( + 'https://bitbucket.mycompany.com/projects/test-project', + ); + }); +}); diff --git a/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.ts b/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.ts new file mode 100644 index 0000000000..025cc555ce --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/lib/BitbucketServerClient.ts @@ -0,0 +1,170 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { fetch, Request } from 'cross-fetch'; +import { + BitbucketServerIntegrationConfig, + getBitbucketServerRequestOptions, +} from '@backstage/integration'; +import { BitbucketServerProject, BitbucketServerRepository } from './types'; + +/** + * A client for interacting with a Bitbucket Server instance + * + * @public + */ +export class BitbucketServerClient { + private readonly config: BitbucketServerIntegrationConfig; + + static fromConfig(options: { + config: BitbucketServerIntegrationConfig; + }): BitbucketServerClient { + return new BitbucketServerClient(options); + } + + constructor(options: { config: BitbucketServerIntegrationConfig }) { + this.config = options.config; + } + + async listProjects(options: { + listOptions?: BitbucketServerListOptions; + }): Promise> { + return this.pagedRequest( + `${this.config.apiBaseUrl}/projects`, + options.listOptions, + ); + } + + async listRepositories(options: { + projectKey: string; + listOptions?: BitbucketServerListOptions; + }): Promise> { + return this.pagedRequest( + `${this.config.apiBaseUrl}/projects/${encodeURIComponent( + options.projectKey, + )}/repos`, + options.listOptions, + ); + } + + async getFile(options: { + projectKey: string; + repo: string; + path: string; + }): Promise { + const base = new URL(this.config.apiBaseUrl); + return fetch( + `${base.protocol}//${base.host}/projects/${options.projectKey}/repos/${options.repo}/raw/${options.path}`, + getBitbucketServerRequestOptions(this.config), + ); + } + + async getRepository(options: { + projectKey: string; + repo: string; + }): Promise { + const request = `${this.config.apiBaseUrl}/projects/${options.projectKey}/repos/${options.repo}`; + const response = await fetch( + request, + getBitbucketServerRequestOptions(this.config), + ); + return response.json(); + } + + resolvePath(options: { projectKey: string; repo: string; path: string }): { + path: string; + } { + const base = new URL(this.config.apiBaseUrl || ''); + + return { + path: `${base.protocol}//${base.host}/projects/${options.projectKey}/repos/${options.repo}${options.path}`, + }; + } + + private async pagedRequest( + endpoint: string, + options?: BitbucketServerListOptions, + ): Promise> { + const request = new URL(endpoint); + for (const key in options) { + if (options[key]) { + request.searchParams.append(key, options[key]!.toString()); + } + } + return this.getTypeMapped(request); + } + + private async getTypeMapped(url: URL): Promise { + return this.get(url).then((response: Response) => { + return response.json() as Promise; + }); + } + + private async get(url: URL): Promise { + return this.request(new Request(url.toString(), { method: 'GET' })); + } + + private async request(req: Request): Promise { + return fetch(req, getBitbucketServerRequestOptions(this.config)).then( + (response: Response) => { + if (!response.ok) { + throw new Error( + `Unexpected response for ${req.method} ${req.url}. Expected 200 but got ${response.status} - ${response.statusText}`, + ); + } + return response; + }, + ); + } +} + +/** + * @public + */ +export type BitbucketServerListOptions = { + [key: string]: number | undefined; + limit?: number | undefined; + start?: number | undefined; +}; + +/** + * @public + */ +export type BitbucketServerPagedResponse = { + size: number; + limit: number; + start: number; + isLastPage: boolean; + values: T[]; + nextPageStart: number; +}; + +export async function* paginated( + request: ( + options: BitbucketServerListOptions, + ) => Promise>, + options?: BitbucketServerListOptions, +) { + const opts = options || { start: 0 }; + let res; + do { + res = await request(opts); + opts.start = res.nextPageStart; + for (const item of res.values) { + yield item; + } + } while (!res.isLastPage); +} diff --git a/plugins/search/src/components/SearchFilter/index.ts b/plugins/catalog-backend-module-bitbucket-server/src/lib/index.ts similarity index 65% rename from plugins/search/src/components/SearchFilter/index.ts rename to plugins/catalog-backend-module-bitbucket-server/src/lib/index.ts index 3050330038..8b72c9335b 100644 --- a/plugins/search/src/components/SearchFilter/index.ts +++ b/plugins/catalog-backend-module-bitbucket-server/src/lib/index.ts @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Backstage Authors + * Copyright 2022 The Backstage Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,9 +14,12 @@ * limitations under the License. */ -export { SearchFilter } from './SearchFilter'; +export { BitbucketServerClient, paginated } from './BitbucketServerClient'; export type { - SearchFilterComponentProps, - SearchFilterWrapperProps, -} from './SearchFilter'; -export type { SearchAutocompleteFilterProps } from './SearchFilter.Autocomplete'; + BitbucketServerPagedResponse, + BitbucketServerListOptions, +} from './BitbucketServerClient'; +export type { + BitbucketServerRepository, + BitbucketServerProject, +} from './types'; diff --git a/plugins/catalog-backend-module-bitbucket-server/src/lib/types.ts b/plugins/catalog-backend-module-bitbucket-server/src/lib/types.ts new file mode 100644 index 0000000000..67a10abea7 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/lib/types.ts @@ -0,0 +1,35 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** @public */ +export type BitbucketServerRepository = { + project: { + key: string; + }; + slug: string; + description: string; + links: Record< + string, + { + href: string; + }[] + >; +}; + +/** @public */ +export type BitbucketServerProject = { + key: string; +}; diff --git a/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts new file mode 100644 index 0000000000..1ebf7c95a7 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.test.ts @@ -0,0 +1,368 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { TaskInvocationDefinition, TaskRunner } from '@backstage/backend-tasks'; +import { ConfigReader } from '@backstage/config'; +import { EntityProviderConnection } from '@backstage/plugin-catalog-backend'; +import { setupRequestMockHandlers } from '@backstage/backend-test-utils'; +import { BitbucketServerEntityProvider } from './BitbucketServerEntityProvider'; +import { rest } from 'msw'; +import { setupServer } from 'msw/node'; +import { BitbucketServerPagedResponse } from '../lib/BitbucketServerClient'; + +class PersistingTaskRunner implements TaskRunner { + private tasks: TaskInvocationDefinition[] = []; + + getTasks() { + return this.tasks; + } + + run(task: TaskInvocationDefinition): Promise { + this.tasks.push(task); + return Promise.resolve(undefined); + } +} + +type Project = { + key: string; + repos: [string]; +}; + +function pagedResponse(values: any): BitbucketServerPagedResponse { + return { + values: values, + isLastPage: true, + } as BitbucketServerPagedResponse; +} + +const logger = getVoidLogger(); + +const server = setupServer(); + +function setupStubs(projects: Project[], baseUrl: string) { + // Stub projects + server.use( + rest.get(`${baseUrl}/rest/api/1.0/projects`, (_, res, ctx) => { + return res( + ctx.json( + pagedResponse( + projects.map(p => { + return { key: p.key }; + }), + ), + ), + ); + }), + ); + + for (const project of projects) { + // Stub list repositories + server.use( + rest.get( + `${baseUrl}/rest/api/1.0/projects/${project.key}/repos`, + (_, res, ctx) => { + const response = []; + for (const repo of project.repos) { + response.push({ + slug: repo, + links: { + self: [ + { + href: `${baseUrl}/projects/${project.key}/repos/${repo}/browse`, + }, + ], + }, + }); + } + return res(ctx.json(pagedResponse(response))); + }, + ), + ); + } +} + +describe('BitbucketServerEntityProvider', () => { + setupRequestMockHandlers(server); + afterEach(() => jest.resetAllMocks()); + + it('no provider config', () => { + const schedule = new PersistingTaskRunner(); + const config = new ConfigReader({}); + const providers = BitbucketServerEntityProvider.fromConfig(config, { + logger, + schedule, + }); + + expect(providers).toHaveLength(0); + }); + + it('rejects no matching integration', () => { + const schedule = new PersistingTaskRunner(); + const config = new ConfigReader({ + catalog: { + providers: { + bitbucketServer: { + mainProvider: { + host: 'bitbucket.mycompany.com', + }, + }, + }, + }, + }); + expect(() => + BitbucketServerEntityProvider.fromConfig(config, { logger, schedule }), + ).toThrow(/bitbucket\.mycompany\.com/); + }); + + it('single simple provider config', () => { + const schedule = new PersistingTaskRunner(); + const config = new ConfigReader({ + catalog: { + providers: { + bitbucketServer: { + host: 'bitbucket.mycompany.com', + }, + }, + }, + integrations: { + bitbucketServer: [ + { + host: 'bitbucket.mycompany.com', + }, + ], + }, + }); + const providers = BitbucketServerEntityProvider.fromConfig(config, { + logger, + schedule, + }); + + expect(providers).toHaveLength(1); + expect(providers[0].getProviderName()).toEqual( + 'bitbucketServer-provider:default', + ); + }); + + it('multiple provider configs', () => { + const schedule = new PersistingTaskRunner(); + const config = new ConfigReader({ + integrations: { + bitbucketServer: [ + { + host: 'bitbucket.mycompany.com', + }, + ], + }, + catalog: { + providers: { + bitbucketServer: { + mainProvider: { + host: 'bitbucket.mycompany.com', + }, + secondary: { + host: 'bitbucket.mycompany.com', + }, + }, + }, + }, + }); + const providers = BitbucketServerEntityProvider.fromConfig(config, { + logger, + schedule, + }); + + expect(providers).toHaveLength(2); + expect(providers[0].getProviderName()).toEqual( + 'bitbucketServer-provider:mainProvider', + ); + expect(providers[1].getProviderName()).toEqual( + 'bitbucketServer-provider:secondary', + ); + }); + + it('apply full update on scheduled execution with filters', async () => { + const host = 'bitbucket.mycompany.com'; + const config = new ConfigReader({ + integrations: { + bitbucketServer: [ + { + host: host, + }, + ], + }, + catalog: { + providers: { + bitbucketServer: { + mainProvider: { + host: host, + filters: { + projectKey: 'project-.*', + repoSlug: 'repo-.*', + }, + }, + }, + }, + }, + }); + const schedule = new PersistingTaskRunner(); + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + }; + const provider = BitbucketServerEntityProvider.fromConfig(config, { + logger, + schedule, + })[0]; + expect(provider.getProviderName()).toEqual( + 'bitbucketServer-provider:mainProvider', + ); + + setupStubs( + [ + { key: 'project-test', repos: ['repo-test'] }, + { key: 'other-project', repos: ['other-repo'] }, + ], + `https://${host}`, + ); + await provider.connect(entityProviderConnection); + + const taskDef = schedule.getTasks()[0]; + expect(taskDef.id).toEqual('bitbucketServer-provider:mainProvider:refresh'); + await (taskDef.fn as () => Promise)(); + + const url = `https://${host}/projects/project-test/repos/repo-test/browse/catalog-info.yaml`; + const expectedEntities = [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + annotations: { + 'backstage.io/managed-by-location': `url:${url}`, + 'backstage.io/managed-by-origin-location': `url:${url}`, + }, + name: 'generated-77f4323822420990f8c3e3c981d38c2dec4ae3a6', + }, + spec: { + presence: 'optional', + target: `${url}`, + type: 'url', + }, + }, + locationKey: 'bitbucketServer-provider:mainProvider', + }, + ]; + + expect(entityProviderConnection.applyMutation).toBeCalledTimes(1); + expect(entityProviderConnection.applyMutation).toBeCalledWith({ + type: 'full', + entities: expectedEntities, + }); + }); + + it('apply full update on scheduled execution without filters', async () => { + const host = 'bitbucket.mycompany.com'; + const config = new ConfigReader({ + integrations: { + bitbucketServer: [ + { + host: host, + }, + ], + }, + catalog: { + providers: { + bitbucketServer: { + mainProvider: { + host: host, + }, + }, + }, + }, + }); + const schedule = new PersistingTaskRunner(); + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + }; + const provider = BitbucketServerEntityProvider.fromConfig(config, { + logger, + schedule, + })[0]; + expect(provider.getProviderName()).toEqual( + 'bitbucketServer-provider:mainProvider', + ); + + setupStubs( + [ + { key: 'project-test', repos: ['repo-test'] }, + { key: 'other-project', repos: ['other-repo'] }, + ], + `https://${host}`, + ); + await provider.connect(entityProviderConnection); + + const taskDef = schedule.getTasks()[0]; + expect(taskDef.id).toEqual('bitbucketServer-provider:mainProvider:refresh'); + await (taskDef.fn as () => Promise)(); + + const expectedEntities = [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + annotations: { + 'backstage.io/managed-by-location': `url:https://${host}/projects/project-test/repos/repo-test/browse/catalog-info.yaml`, + 'backstage.io/managed-by-origin-location': `url:https://${host}/projects/project-test/repos/repo-test/browse/catalog-info.yaml`, + }, + name: 'generated-77f4323822420990f8c3e3c981d38c2dec4ae3a6', + }, + spec: { + presence: 'optional', + target: `https://${host}/projects/project-test/repos/repo-test/browse/catalog-info.yaml`, + type: 'url', + }, + }, + locationKey: 'bitbucketServer-provider:mainProvider', + }, + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + annotations: { + 'backstage.io/managed-by-location': `url:https://${host}/projects/other-project/repos/other-repo/browse/catalog-info.yaml`, + 'backstage.io/managed-by-origin-location': `url:https://${host}/projects/other-project/repos/other-repo/browse/catalog-info.yaml`, + }, + name: 'generated-d8d4944c30c2906dfee172ddda9537f9893b2c0f', + }, + spec: { + presence: 'optional', + target: `https://${host}/projects/other-project/repos/other-repo/browse/catalog-info.yaml`, + type: 'url', + }, + }, + locationKey: 'bitbucketServer-provider:mainProvider', + }, + ]; + + expect(entityProviderConnection.applyMutation).toBeCalledTimes(1); + expect(entityProviderConnection.applyMutation).toBeCalledWith({ + type: 'full', + entities: expectedEntities, + }); + }); +}); diff --git a/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.ts b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.ts new file mode 100644 index 0000000000..92cecf642a --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProvider.ts @@ -0,0 +1,200 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + EntityProvider, + EntityProviderConnection, +} from '@backstage/plugin-catalog-backend'; +import { Logger } from 'winston'; +import { Config } from '@backstage/config'; +import { TaskRunner } from '@backstage/backend-tasks'; +import * as uuid from 'uuid'; +import { + BitbucketServerLocationParser, + defaultBitbucketServerLocationParser, +} from './BitbucketServerLocationParser'; +import { + BitbucketServerIntegration, + ScmIntegrations, +} from '@backstage/integration'; +import { BitbucketServerClient, paginated } from '../lib'; +import { InputError } from '@backstage/errors'; +import { + BitbucketServerEntityProviderConfig, + readProviderConfigs, +} from './BitbucketServerEntityProviderConfig'; +import { Entity } from '@backstage/catalog-model'; + +/** + * Discovers catalog files located in Bitbucket Server. + * The provider will search your Bitbucket Server instance and register catalog files matching the configured path + * as Location entity and via following processing steps add all contained catalog entities. + * This can be useful as an alternative to static locations or manually adding things to the catalog. + * + * @public + */ +export class BitbucketServerEntityProvider implements EntityProvider { + private readonly integration: BitbucketServerIntegration; + private readonly config: BitbucketServerEntityProviderConfig; + private readonly parser: BitbucketServerLocationParser; + private readonly logger: Logger; + private readonly scheduleFn: () => Promise; + private connection?: EntityProviderConnection; + + static fromConfig( + config: Config, + options: { + logger: Logger; + schedule: TaskRunner; + parser?: BitbucketServerLocationParser; + }, + ): BitbucketServerEntityProvider[] { + const integrations = ScmIntegrations.fromConfig(config); + + return readProviderConfigs(config).map(providerConfig => { + const integration = integrations.bitbucketServer.byHost( + providerConfig.host, + ); + if (!integration) { + throw new InputError( + `No BitbucketServer integration found that matches host ${providerConfig.host}`, + ); + } + return new BitbucketServerEntityProvider( + providerConfig, + integration, + options.logger, + options.schedule, + options.parser, + ); + }); + } + + private constructor( + config: BitbucketServerEntityProviderConfig, + integration: BitbucketServerIntegration, + logger: Logger, + schedule: TaskRunner, + parser?: BitbucketServerLocationParser, + ) { + this.integration = integration; + this.config = config; + this.parser = parser || defaultBitbucketServerLocationParser; + this.logger = logger.child({ + target: this.getProviderName(), + }); + this.scheduleFn = this.createScheduleFn(schedule); + } + + private createScheduleFn(schedule: TaskRunner): () => Promise { + return async () => { + const taskId = `${this.getProviderName()}:refresh`; + return schedule.run({ + id: taskId, + fn: async () => { + const logger = this.logger.child({ + class: BitbucketServerEntityProvider.prototype.constructor.name, + taskId, + taskInstanceId: uuid.v4(), + }); + + try { + await this.refresh(logger); + } catch (error) { + logger.error(error); + } + }, + }); + }; + } + + /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */ + getProviderName(): string { + return `bitbucketServer-provider:${this.config.id}`; + } + + /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */ + async connect(connection: EntityProviderConnection): Promise { + this.connection = connection; + await this.scheduleFn(); + } + + async refresh(logger: Logger) { + if (!this.connection) { + throw new Error('Not initialized'); + } + + logger.info('Discovering catalog files in Bitbucket Server repositories'); + + const entities = await this.findEntities(); + + await this.connection.applyMutation({ + type: 'full', + entities: entities.map(entity => ({ + locationKey: this.getProviderName(), + entity: entity, + })), + }); + + logger.info( + `Committed ${entities.length} entities for Bitbucket Server repositories`, + ); + } + + private async findEntities(): Promise { + const client = BitbucketServerClient.fromConfig({ + config: this.integration.config, + }); + const projects = paginated(options => + client.listProjects({ listOptions: options }), + ); + const result: Entity[] = []; + for await (const project of projects) { + if ( + this.config?.filters?.projectKey && + !this.config.filters.projectKey.test(project.key) + ) { + continue; + } + const repositories = paginated(options => + client.listRepositories({ + projectKey: project.key, + listOptions: options, + }), + ); + for await (const repository of repositories) { + if ( + this.config?.filters?.repoSlug && + !this.config.filters.repoSlug.test(repository.slug) + ) { + continue; + } + for await (const entity of this.parser({ + client, + logger: this.logger, + location: { + type: 'url', + target: `${repository.links.self[0].href}${this.config.catalogPath}`, + presence: 'optional', + }, + })) { + result.push(entity); + } + } + } + return result; + } +} diff --git a/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProviderConfig.test.ts b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProviderConfig.test.ts new file mode 100644 index 0000000000..712b26cbb0 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProviderConfig.test.ts @@ -0,0 +1,122 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigReader } from '@backstage/config'; +import { readProviderConfigs } from './BitbucketServerEntityProviderConfig'; + +describe('readProviderConfigs', () => { + afterEach(() => jest.resetAllMocks()); + + it('no provider config', () => { + const config = new ConfigReader({}); + const providerConfigs = readProviderConfigs(config); + + expect(providerConfigs).toHaveLength(0); + }); + + it('single simple provider config', () => { + const config = new ConfigReader({ + catalog: { + providers: { + bitbucketServer: { + host: 'bitbucket.mycompany.com', + }, + }, + }, + }); + const providerConfigs = readProviderConfigs(config); + + expect(providerConfigs).toHaveLength(1); + expect(providerConfigs[0]).toEqual({ + id: 'default', + catalogPath: '/catalog-info.yaml', + host: 'bitbucket.mycompany.com', + filters: { + projectKey: undefined, + repoSlug: undefined, + }, + }); + }); + + it('multiple provider configs', () => { + const config = new ConfigReader({ + catalog: { + providers: { + bitbucketServer: { + mainProvider: { + host: 'bitbucket.mycompany.com', + }, + secondaryProvider: { + host: 'bitbucket2.mycompany.com', + catalogPath: 'custom/path/catalog-info.yaml', + }, + }, + }, + }, + }); + const providerConfigs = readProviderConfigs(config); + + expect(providerConfigs).toHaveLength(2); + expect(providerConfigs[0]).toEqual({ + id: 'mainProvider', + catalogPath: '/catalog-info.yaml', + host: 'bitbucket.mycompany.com', + filters: { + projectKey: undefined, + repoSlug: undefined, + }, + }); + expect(providerConfigs[1]).toEqual({ + id: 'secondaryProvider', + catalogPath: 'custom/path/catalog-info.yaml', + host: 'bitbucket2.mycompany.com', + filters: { + projectKey: undefined, + repoSlug: undefined, + }, + }); + }); + + it('single provider config with filters', () => { + const config = new ConfigReader({ + catalog: { + providers: { + bitbucketServer: { + mainProvider: { + host: 'bitbucket.mycompany.com', + filters: { + projectKey: 'project1', + repoSlug: '.*', + }, + }, + }, + }, + }, + }); + const providerConfigs = readProviderConfigs(config); + + expect(providerConfigs).toHaveLength(1); + expect(providerConfigs[0]).toEqual({ + id: 'mainProvider', + catalogPath: '/catalog-info.yaml', + host: 'bitbucket.mycompany.com', + filters: { + projectKey: /project1/, + repoSlug: /.*/, + }, + }); + }); +}); diff --git a/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProviderConfig.ts b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProviderConfig.ts new file mode 100644 index 0000000000..8a3decab43 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerEntityProviderConfig.ts @@ -0,0 +1,72 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Config } from '@backstage/config'; + +const DEFAULT_CATALOG_PATH = '/catalog-info.yaml'; +const DEFAULT_PROVIDER_ID = 'default'; + +export type BitbucketServerEntityProviderConfig = { + id: string; + host: string; + catalogPath: string; + filters?: { + projectKey?: RegExp; + repoSlug?: RegExp; + }; +}; + +export function readProviderConfigs( + config: Config, +): BitbucketServerEntityProviderConfig[] { + const providersConfig = config.getOptionalConfig( + 'catalog.providers.bitbucketServer', + ); + if (!providersConfig) { + return []; + } + if (providersConfig.has('host')) { + // simple/single config variant + return [readProviderConfig(DEFAULT_PROVIDER_ID, providersConfig)]; + } + + return providersConfig.keys().map(id => { + const providerConfig = providersConfig.getConfig(id); + + return readProviderConfig(id, providerConfig); + }); +} + +function readProviderConfig( + id: string, + config: Config, +): BitbucketServerEntityProviderConfig { + const host = config.getString('host'); + const catalogPath = + config.getOptionalString('catalogPath') ?? DEFAULT_CATALOG_PATH; + const projectKeyPattern = config.getOptionalString('filters.projectKey'); + const repoSlugPattern = config.getOptionalString('filters.repoSlug'); + + return { + id, + host, + catalogPath, + filters: { + projectKey: projectKeyPattern ? new RegExp(projectKeyPattern) : undefined, + repoSlug: repoSlugPattern ? new RegExp(repoSlugPattern) : undefined, + }, + }; +} diff --git a/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerLocationParser.ts b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerLocationParser.ts new file mode 100644 index 0000000000..7f6dae8872 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/providers/BitbucketServerLocationParser.ts @@ -0,0 +1,42 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + LocationSpec, + locationSpecToLocationEntity, +} from '@backstage/plugin-catalog-backend'; +import { Entity } from '@backstage/catalog-model'; +import { Logger } from 'winston'; +import { BitbucketServerClient } from '../lib'; + +/** + * A custom callback that reacts to finding a location by yielding entities. + * Can be used for custom location/repository parsing logic. + * + * @public + */ +export type BitbucketServerLocationParser = (options: { + client: BitbucketServerClient; + location: LocationSpec; + logger: Logger; +}) => AsyncIterable; + +export const defaultBitbucketServerLocationParser = + async function* defaultBitbucketServerLocationParser(options: { + location: LocationSpec; + }) { + yield locationSpecToLocationEntity({ location: options.location }); + }; diff --git a/plugins/catalog-backend-module-bitbucket-server/src/providers/index.ts b/plugins/catalog-backend-module-bitbucket-server/src/providers/index.ts new file mode 100644 index 0000000000..8c6430a558 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/providers/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { BitbucketServerEntityProvider } from './BitbucketServerEntityProvider'; +export type { BitbucketServerLocationParser } from './BitbucketServerLocationParser'; diff --git a/plugins/catalog-backend-module-bitbucket-server/src/setupTests.ts b/plugins/catalog-backend-module-bitbucket-server/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/catalog-backend-module-bitbucket-server/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export {}; diff --git a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md index b73c4834c4..1f1761bc71 100644 --- a/plugins/catalog-backend-module-bitbucket/CHANGELOG.md +++ b/plugins/catalog-backend-module-bitbucket/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-catalog-backend-module-bitbucket +## 0.2.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/plugin-catalog-backend@1.3.1 + - @backstage/plugin-bitbucket-cloud-common@0.1.2 + +## 0.2.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + - @backstage/plugin-bitbucket-cloud-common@0.1.2-next.0 + +## 0.2.1 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/plugin-bitbucket-cloud-common@0.1.1 + - @backstage/errors@1.1.0 + ## 0.2.1-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-bitbucket/package.json b/plugins/catalog-backend-module-bitbucket/package.json index a01a2e38ce..e67d1267f4 100644 --- a/plugins/catalog-backend-module-bitbucket/package.json +++ b/plugins/catalog-backend-module-bitbucket/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-bitbucket", "description": "A Backstage catalog backend module that helps integrate towards Bitbucket", - "version": "0.2.1-next.2", + "version": "0.2.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,22 +33,22 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-bitbucket-cloud-common": "^0.1.1-next.1", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-bitbucket-cloud-common": "^0.1.2", + "@backstage/plugin-catalog-backend": "^1.3.1", "@backstage/types": "^1.0.0", "lodash": "^4.17.21", - "msw": "^0.44.0", + "msw": "^0.45.0", "node-fetch": "^2.6.7", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "@types/lodash": "^4.14.151" }, "files": [ diff --git a/plugins/catalog-backend-module-gerrit/CHANGELOG.md b/plugins/catalog-backend-module-gerrit/CHANGELOG.md index 3658da2d54..b4292da75c 100644 --- a/plugins/catalog-backend-module-gerrit/CHANGELOG.md +++ b/plugins/catalog-backend-module-gerrit/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-catalog-backend-module-gerrit +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## 0.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + ## 0.1.2-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-gerrit/package.json b/plugins/catalog-backend-module-gerrit/package.json index e56e199d59..b068709b96 100644 --- a/plugins/catalog-backend-module-gerrit/package.json +++ b/plugins/catalog-backend-module-gerrit/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-backend-module-gerrit", - "version": "0.1.2-next.2", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,22 +28,22 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/backend-tasks": "^0.3.3-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-tasks": "^0.3.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-backend": "^1.3.1", "fs-extra": "10.1.0", - "msw": "^0.44.0", + "msw": "^0.45.0", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "@types/fs-extra": "^9.0.1" }, "files": [ diff --git a/plugins/catalog-backend-module-github/CHANGELOG.md b/plugins/catalog-backend-module-github/CHANGELOG.md index bf96849eca..2e9c03529b 100644 --- a/plugins/catalog-backend-module-github/CHANGELOG.md +++ b/plugins/catalog-backend-module-github/CHANGELOG.md @@ -1,5 +1,71 @@ # @backstage/plugin-catalog-backend-module-github +## 0.1.6 + +### Patch Changes + +- f48950e34b: Github Entity Provider functionality for adding entities to the catalog. + + This provider replaces the GithubDiscoveryProcessor functionality as providers offer more flexibility with scheduling ingestion, removing and preventing orphaned entities. + + More information can be found on the [GitHub Discovery](https://backstage.io/docs/integrations/github/discovery) page. + +- c59d1ce487: Fixed bug where repository filter was including all archived repositories +- 97f0a37378: Improved support for wildcards in `catalogPath` +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## 0.1.6-next.2 + +### Patch Changes + +- 97f0a37378: Improved support for wildcards in `catalogPath` +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.1-next.2 + +## 0.1.6-next.1 + +### Patch Changes + +- f48950e34b: Github Entity Provider functionality for adding entities to the catalog. + + This provider replaces the GithubDiscoveryProcessor functionality as providers offer more flexibility with scheduling ingestion, removing and preventing orphaned entities. + + More information can be found on the [GitHub Discovery](https://backstage.io/docs/integrations/github/discovery) page. + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-catalog-backend@1.3.1-next.1 + +## 0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## 0.1.5 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 0f25116d28: Updated dependency `@octokit/graphql` to `^5.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + ## 0.1.5-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-github/api-report.md b/plugins/catalog-backend-module-github/api-report.md index e5fa2ea46a..8e8055bafc 100644 --- a/plugins/catalog-backend-module-github/api-report.md +++ b/plugins/catalog-backend-module-github/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 { CatalogProcessor } from '@backstage/plugin-catalog-backend'; import { CatalogProcessorEmit } from '@backstage/plugin-catalog-backend'; import { Config } from '@backstage/config'; @@ -14,6 +15,7 @@ import { LocationSpec } from '@backstage/plugin-catalog-backend'; import { Logger } from 'winston'; import { ScmIntegrationRegistry } from '@backstage/integration'; import { TaskRunner } from '@backstage/backend-tasks'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; // @public export class GithubDiscoveryProcessor implements CatalogProcessor { @@ -40,6 +42,34 @@ export class GithubDiscoveryProcessor implements CatalogProcessor { ): Promise; } +// @public +export class GitHubEntityProvider implements EntityProvider { + // (undocumented) + connect(connection: EntityProviderConnection): Promise; + // (undocumented) + static fromConfig( + config: Config, + options: { + logger: Logger; + schedule: TaskRunner; + }, + ): GitHubEntityProvider[]; + // (undocumented) + getProviderName(): string; + // (undocumented) + refresh(logger: Logger): Promise; +} + +// @alpha +export const githubEntityProviderCatalogModule: ( + options?: GithubEntityProviderCatalogModuleOptions | undefined, +) => BackendFeature; + +// @alpha +export type GithubEntityProviderCatalogModuleOptions = { + schedule?: TaskScheduleDefinition; +}; + // @public export type GithubMultiOrgConfig = Array<{ name: string; diff --git a/plugins/catalog-backend-module-github/package.json b/plugins/catalog-backend-module-github/package.json index 7d52be20de..4c9202e6f5 100644 --- a/plugins/catalog-backend-module-github/package.json +++ b/plugins/catalog-backend-module-github/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-github", "description": "A Backstage catalog backend module that helps integrate towards GitHub", - "version": "0.1.5-next.2", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -9,7 +9,8 @@ "publishConfig": { "access": "public", "main": "dist/index.cjs.js", - "types": "dist/index.d.ts" + "types": "dist/index.d.ts", + "alphaTypes": "dist/index.alpha.d.ts" }, "backstage": { "role": "backend-plugin-module" @@ -24,7 +25,7 @@ "backstage" ], "scripts": { - "build": "backstage-cli package build", + "build": "backstage-cli package build --experimental-type-build", "lint": "backstage-cli package lint", "test": "backstage-cli package test", "prepack": "backstage-cli package prepack", @@ -33,28 +34,31 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/backend-tasks": "^0.3.3-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-tasks": "^0.3.4", + "@backstage/backend-plugin-api": "^0.1.1", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-backend": "^1.3.1", + "@backstage/plugin-catalog-node": "^1.0.1", "@backstage/types": "^1.0.0", "@octokit/graphql": "^5.0.0", "lodash": "^4.17.21", - "msw": "^0.44.0", + "msw": "^0.45.0", "node-fetch": "^2.6.7", "uuid": "^8.0.0", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "@types/lodash": "^4.14.151" }, "files": [ "dist", + "alpha", "config.d.ts" ], "configSchema": "config.d.ts" diff --git a/plugins/catalog-backend-module-github/src/index.ts b/plugins/catalog-backend-module-github/src/index.ts index 2f666e6547..d793d48f1e 100644 --- a/plugins/catalog-backend-module-github/src/index.ts +++ b/plugins/catalog-backend-module-github/src/index.ts @@ -20,9 +20,12 @@ * @packageDocumentation */ -export { GithubDiscoveryProcessor } from './GithubDiscoveryProcessor'; -export { GithubMultiOrgReaderProcessor } from './GithubMultiOrgReaderProcessor'; -export { GitHubOrgEntityProvider } from './GitHubOrgEntityProvider'; -export type { GitHubOrgEntityProviderOptions } from './GitHubOrgEntityProvider'; -export { GithubOrgReaderProcessor } from './GithubOrgReaderProcessor'; +export { GithubDiscoveryProcessor } from './processors/GithubDiscoveryProcessor'; +export { GithubMultiOrgReaderProcessor } from './processors/GithubMultiOrgReaderProcessor'; +export { GithubOrgReaderProcessor } from './processors/GithubOrgReaderProcessor'; +export { GitHubEntityProvider } from './providers/GitHubEntityProvider'; +export { GitHubOrgEntityProvider } from './providers/GitHubOrgEntityProvider'; +export type { GitHubOrgEntityProviderOptions } from './providers/GitHubOrgEntityProvider'; export type { GithubMultiOrgConfig } from './lib'; +export { githubEntityProviderCatalogModule } from './module'; +export type { GithubEntityProviderCatalogModuleOptions } from './module'; diff --git a/plugins/catalog-backend-module-github/src/module.ts b/plugins/catalog-backend-module-github/src/module.ts new file mode 100644 index 0000000000..4eccef0611 --- /dev/null +++ b/plugins/catalog-backend-module-github/src/module.ts @@ -0,0 +1,69 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createBackendModule, + loggerToWinstonLogger, + configServiceRef, + loggerServiceRef, + schedulerServiceRef, +} from '@backstage/backend-plugin-api'; +import { TaskScheduleDefinition } from '@backstage/backend-tasks'; +import { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node'; +import { GitHubEntityProvider } from './providers/GitHubEntityProvider'; + +/** + * Options for {@link githubEntityProviderCatalogModule}. + * + * @alpha + */ +export type GithubEntityProviderCatalogModuleOptions = { + schedule?: TaskScheduleDefinition; +}; + +/** + * Registers the GitHubEntityProvider with the catalog processing extension point. + * + * @alpha + */ +export const githubEntityProviderCatalogModule = createBackendModule({ + pluginId: 'catalog', + moduleId: 'github-entity-provider', + register(env, options?: GithubEntityProviderCatalogModuleOptions) { + env.registerInit({ + deps: { + config: configServiceRef, + catalog: catalogProcessingExtensionPoint, + logger: loggerServiceRef, + scheduler: schedulerServiceRef, + }, + async init({ config, catalog, logger, scheduler }) { + const scheduleDef = options?.schedule ?? { + frequency: { seconds: 600 }, + timeout: { seconds: 900 }, + initialDelay: { seconds: 3 }, + }; + + catalog.addEntityProvider( + GitHubEntityProvider.fromConfig(config, { + logger: loggerToWinstonLogger(logger), + schedule: scheduler.createScheduledTaskRunner(scheduleDef), + }), + ); + }, + }); + }, +}); diff --git a/plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.test.ts b/plugins/catalog-backend-module-github/src/processors/GithubDiscoveryProcessor.test.ts similarity index 99% rename from plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.test.ts rename to plugins/catalog-backend-module-github/src/processors/GithubDiscoveryProcessor.test.ts index b18e3baf75..7ce6f3f9cf 100644 --- a/plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.test.ts +++ b/plugins/catalog-backend-module-github/src/processors/GithubDiscoveryProcessor.test.ts @@ -22,9 +22,9 @@ import { } from '@backstage/integration'; import { LocationSpec } from '@backstage/plugin-catalog-backend'; import { GithubDiscoveryProcessor, parseUrl } from './GithubDiscoveryProcessor'; -import { getOrganizationRepositories } from './lib'; +import { getOrganizationRepositories } from '../lib'; -jest.mock('./lib'); +jest.mock('../lib'); const mockGetOrganizationRepositories = getOrganizationRepositories as jest.MockedFunction< typeof getOrganizationRepositories diff --git a/plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.ts b/plugins/catalog-backend-module-github/src/processors/GithubDiscoveryProcessor.ts similarity index 99% rename from plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.ts rename to plugins/catalog-backend-module-github/src/processors/GithubDiscoveryProcessor.ts index 78a1bca169..97c77bf033 100644 --- a/plugins/catalog-backend-module-github/src/GithubDiscoveryProcessor.ts +++ b/plugins/catalog-backend-module-github/src/processors/GithubDiscoveryProcessor.ts @@ -29,7 +29,7 @@ import { } from '@backstage/plugin-catalog-backend'; import { graphql } from '@octokit/graphql'; import { Logger } from 'winston'; -import { getOrganizationRepositories } from './lib'; +import { getOrganizationRepositories } from '../lib'; /** * Extracts repositories out of a GitHub org. diff --git a/plugins/catalog-backend-module-github/src/GithubMultiOrgReaderProcessor.ts b/plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts similarity index 99% rename from plugins/catalog-backend-module-github/src/GithubMultiOrgReaderProcessor.ts rename to plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts index 321e9cc8f8..c5315ad166 100644 --- a/plugins/catalog-backend-module-github/src/GithubMultiOrgReaderProcessor.ts +++ b/plugins/catalog-backend-module-github/src/processors/GithubMultiOrgReaderProcessor.ts @@ -37,7 +37,7 @@ import { getOrganizationUsers, GithubMultiOrgConfig, readGithubMultiOrgConfig, -} from './lib'; +} from '../lib'; /** * Extracts teams and users out of a multiple GitHub orgs namespaced per org. diff --git a/plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.test.ts b/plugins/catalog-backend-module-github/src/processors/GithubOrgReaderProcessor.test.ts similarity index 100% rename from plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.test.ts rename to plugins/catalog-backend-module-github/src/processors/GithubOrgReaderProcessor.test.ts diff --git a/plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.ts b/plugins/catalog-backend-module-github/src/processors/GithubOrgReaderProcessor.ts similarity index 99% rename from plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.ts rename to plugins/catalog-backend-module-github/src/processors/GithubOrgReaderProcessor.ts index ca1dd96b3c..c6f2f5d0e2 100644 --- a/plugins/catalog-backend-module-github/src/GithubOrgReaderProcessor.ts +++ b/plugins/catalog-backend-module-github/src/processors/GithubOrgReaderProcessor.ts @@ -36,7 +36,7 @@ import { getOrganizationTeams, getOrganizationUsers, parseGitHubOrgUrl, -} from './lib'; +} from '../lib'; type GraphQL = typeof graphql; diff --git a/plugins/catalog-backend-module-github/src/providers/GitHubEntityProvider.test.ts b/plugins/catalog-backend-module-github/src/providers/GitHubEntityProvider.test.ts new file mode 100644 index 0000000000..a40ab4eb5c --- /dev/null +++ b/plugins/catalog-backend-module-github/src/providers/GitHubEntityProvider.test.ts @@ -0,0 +1,185 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import { TaskInvocationDefinition, TaskRunner } from '@backstage/backend-tasks'; +import { ConfigReader } from '@backstage/config'; +import { EntityProviderConnection } from '@backstage/plugin-catalog-backend'; +import { GitHubEntityProvider } from './GitHubEntityProvider'; +import * as helpers from '../lib/github'; + +class PersistingTaskRunner implements TaskRunner { + private tasks: TaskInvocationDefinition[] = []; + + getTasks() { + return this.tasks; + } + + run(task: TaskInvocationDefinition): Promise { + this.tasks.push(task); + return Promise.resolve(undefined); + } +} + +const logger = getVoidLogger(); + +describe('GitHubEntityProvider', () => { + afterEach(() => jest.resetAllMocks()); + + it('no provider config', () => { + const schedule = new PersistingTaskRunner(); + const config = new ConfigReader({}); + const providers = GitHubEntityProvider.fromConfig(config, { + logger, + schedule, + }); + + expect(providers).toHaveLength(0); + }); + + it('single simple provider config', () => { + const schedule = new PersistingTaskRunner(); + const config = new ConfigReader({ + catalog: { + providers: { + github: { + organization: 'test-org', + }, + }, + }, + }); + const providers = GitHubEntityProvider.fromConfig(config, { + logger, + schedule, + }); + + expect(providers).toHaveLength(1); + expect(providers[0].getProviderName()).toEqual('github-provider:default'); + }); + + it('multiple provider configs', () => { + const schedule = new PersistingTaskRunner(); + const config = new ConfigReader({ + catalog: { + providers: { + github: { + myProvider: { + organization: 'test-org1', + }, + anotherProvider: { + organization: 'test-org2', + }, + }, + }, + }, + }); + const providers = GitHubEntityProvider.fromConfig(config, { + logger, + schedule, + }); + + expect(providers).toHaveLength(2); + expect(providers[0].getProviderName()).toEqual( + 'github-provider:myProvider', + ); + expect(providers[1].getProviderName()).toEqual( + 'github-provider:anotherProvider', + ); + }); + + it('apply full update on scheduled execution', async () => { + const config = new ConfigReader({ + catalog: { + providers: { + github: { + myProvider: { + organization: 'test-org', + catalogPath: 'custom/path/catalog-custom.yaml', + filters: { + branch: 'main', + repository: 'test-.*', + }, + }, + }, + }, + }, + }); + const schedule = new PersistingTaskRunner(); + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + }; + + const provider = GitHubEntityProvider.fromConfig(config, { + logger, + schedule, + })[0]; + + const mockGetOrganizationRepositories = jest.spyOn( + helpers, + 'getOrganizationRepositories', + ); + + mockGetOrganizationRepositories.mockReturnValue( + Promise.resolve({ + repositories: [ + { + name: 'test-repo', + url: 'https://github.com/test-org/test-repo', + isArchived: false, + defaultBranchRef: { + name: 'main', + }, + }, + ], + }), + ); + + await provider.connect(entityProviderConnection); + + const taskDef = schedule.getTasks()[0]; + expect(taskDef.id).toEqual('github-provider:myProvider:refresh'); + await (taskDef.fn as () => Promise)(); + + const url = `https://github.com/test-org/test-repo/blob/main/custom/path/catalog-custom.yaml`; + const expectedEntities = [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + annotations: { + 'backstage.io/managed-by-location': `url:${url}`, + 'backstage.io/managed-by-origin-location': `url:${url}`, + }, + name: 'generated-5e4b9498097f15434e88c477cfba6c079aa8ca7f', + }, + spec: { + presence: 'optional', + target: `${url}`, + type: 'url', + }, + }, + locationKey: 'github-provider:myProvider', + }, + ]; + + expect(entityProviderConnection.applyMutation).toBeCalledTimes(1); + expect(entityProviderConnection.applyMutation).toBeCalledWith({ + type: 'full', + entities: expectedEntities, + }); + }); +}); diff --git a/plugins/catalog-backend-module-github/src/providers/GitHubEntityProvider.ts b/plugins/catalog-backend-module-github/src/providers/GitHubEntityProvider.ts new file mode 100644 index 0000000000..eb5b9d67e2 --- /dev/null +++ b/plugins/catalog-backend-module-github/src/providers/GitHubEntityProvider.ts @@ -0,0 +1,255 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { TaskRunner } from '@backstage/backend-tasks'; +import { Config } from '@backstage/config'; +import { + GithubCredentialsProvider, + ScmIntegrations, + GitHubIntegrationConfig, + GitHubIntegration, + SingleInstanceGithubCredentialsProvider, +} from '@backstage/integration'; +import { + EntityProvider, + EntityProviderConnection, + LocationSpec, + locationSpecToLocationEntity, +} from '@backstage/plugin-catalog-backend'; + +import { graphql } from '@octokit/graphql'; +import * as uuid from 'uuid'; +import { Logger } from 'winston'; +import { + readProviderConfigs, + GitHubEntityProviderConfig, +} from './GitHubEntityProviderConfig'; +import { getOrganizationRepositories, Repository } from '../lib/github'; + +/** + * Discovers catalog files located in [GitHub](https://github.com). + * The provider will search your GitHub account and register catalog files matching the configured path + * as Location entity and via following processing steps add all contained catalog entities. + * This can be useful as an alternative to static locations or manually adding things to the catalog. + * + * @public + */ +export class GitHubEntityProvider implements EntityProvider { + private readonly config: GitHubEntityProviderConfig; + private readonly logger: Logger; + private readonly integration: GitHubIntegrationConfig; + private readonly scheduleFn: () => Promise; + private connection?: EntityProviderConnection; + private readonly githubCredentialsProvider: GithubCredentialsProvider; + + static fromConfig( + config: Config, + options: { + logger: Logger; + schedule: TaskRunner; + }, + ): GitHubEntityProvider[] { + const integrations = ScmIntegrations.fromConfig(config); + const integration = integrations.github.byHost('github.com'); + + if (!integration) { + throw new Error( + `There is no GitHub config that matches github. Please add a configuration entry for it under integrations.github`, + ); + } + + return readProviderConfigs(config).map( + providerConfig => + new GitHubEntityProvider( + providerConfig, + integration, + options.logger, + options.schedule, + ), + ); + } + + private constructor( + config: GitHubEntityProviderConfig, + integration: GitHubIntegration, + logger: Logger, + schedule: TaskRunner, + ) { + this.config = config; + this.integration = integration.config; + this.logger = logger.child({ + target: this.getProviderName(), + }); + this.scheduleFn = this.createScheduleFn(schedule); + this.githubCredentialsProvider = + SingleInstanceGithubCredentialsProvider.create(integration.config); + this.scheduleFn = this.createScheduleFn(schedule); + } + + /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.getProviderName} */ + getProviderName(): string { + return `github-provider:${this.config.id}`; + } + + /** {@inheritdoc @backstage/plugin-catalog-backend#EntityProvider.connect} */ + async connect(connection: EntityProviderConnection): Promise { + this.connection = connection; + return await this.scheduleFn(); + } + + private createScheduleFn(schedule: TaskRunner): () => Promise { + return async () => { + const taskId = `${this.getProviderName()}:refresh`; + return schedule.run({ + id: taskId, + fn: async () => { + const logger = this.logger.child({ + class: GitHubEntityProvider.prototype.constructor.name, + taskId, + taskInstanceId: uuid.v4(), + }); + try { + await this.refresh(logger); + } catch (error) { + logger.error(error); + } + }, + }); + }; + } + + async refresh(logger: Logger) { + if (!this.connection) { + throw new Error('Not initialized'); + } + + const targets = await this.findCatalogFiles(); + const matchingTargets = this.matchesFilters(targets); + const entities = matchingTargets + .map(repository => this.createLocationUrl(repository)) + .map(GitHubEntityProvider.toLocationSpec) + .map(location => { + return { + locationKey: this.getProviderName(), + entity: locationSpecToLocationEntity({ location }), + }; + }); + + await this.connection.applyMutation({ + type: 'full', + entities, + }); + + logger.info( + `Read ${targets.length} GitHub repositories (${entities.length} matching the pattern)`, + ); + } + + // go to the server and get all of the repositories + private async findCatalogFiles(): Promise { + const organization = this.config.organization; + const host = this.integration.host; + const orgUrl = `https://${host}/${organization}`; + + const { headers } = await this.githubCredentialsProvider.getCredentials({ + url: orgUrl, + }); + + const client = graphql.defaults({ + baseUrl: this.integration.apiBaseUrl, + headers, + }); + + const { repositories } = await getOrganizationRepositories( + client, + organization, + ); + + return repositories; + } + + private matchesFilters(repositories: Repository[]) { + const repositoryFilter = this.config.filters?.repository; + + const matchingRepositories = repositories.filter(r => { + return ( + !r.isArchived && + (!repositoryFilter || repositoryFilter.test(r.name)) && + r.defaultBranchRef?.name + ); + }); + return matchingRepositories; + } + + private createLocationUrl(repository: Repository): string { + const branch = + this.config.filters?.branch || repository.defaultBranchRef?.name || '-'; + const catalogFile = this.config.catalogPath.startsWith('/') + ? this.config.catalogPath.substring(1) + : this.config.catalogPath; + return `${repository.url}/blob/${branch}/${catalogFile}`; + } + + private static toLocationSpec(target: string): LocationSpec { + return { + type: 'url', + target: target, + presence: 'optional', + }; + } +} + +/* + * Helpers + */ + +export function parseUrl(urlString: string): { + org: string; + repoSearchPath: RegExp; + catalogPath: string; + branch: string; + host: string; +} { + const url = new URL(urlString); + const path = url.pathname.substr(1).split('/'); + + // /backstage/techdocs-*/blob/master/catalog-info.yaml + // can also be + // /backstage + if (path.length > 2 && path[0].length && path[1].length) { + return { + org: decodeURIComponent(path[0]), + repoSearchPath: escapeRegExp(decodeURIComponent(path[1])), + catalogPath: `/${decodeURIComponent(path.slice(4).join('/'))}`, + branch: decodeURIComponent(path[3]), + host: url.host, + }; + } else if (path.length === 1 && path[0].length) { + return { + org: decodeURIComponent(path[0]), + repoSearchPath: escapeRegExp('*'), + catalogPath: '/catalog-info.yaml', + branch: '-', + host: url.host, + }; + } + + throw new Error(`Failed to parse ${urlString}`); +} + +export function escapeRegExp(str: string): RegExp { + return new RegExp(`^${str.replace(/\*/g, '.*')}$`); +} diff --git a/plugins/catalog-backend-module-github/src/providers/GitHubEntityProviderConfig.test.ts b/plugins/catalog-backend-module-github/src/providers/GitHubEntityProviderConfig.test.ts new file mode 100644 index 0000000000..ba72dbf950 --- /dev/null +++ b/plugins/catalog-backend-module-github/src/providers/GitHubEntityProviderConfig.test.ts @@ -0,0 +1,115 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigReader } from '@backstage/config'; +import { readProviderConfigs } from './GitHubEntityProviderConfig'; + +describe('readProviderConfigs', () => { + afterEach(() => jest.resetAllMocks()); + + it('no provider config', () => { + const config = new ConfigReader({}); + const providerConfigs = readProviderConfigs(config); + + expect(providerConfigs).toHaveLength(0); + }); + + it('single simple provider config', () => { + const config = new ConfigReader({ + catalog: { + providers: { + github: { + organization: 'test-org', + }, + }, + }, + }); + const providerConfigs = readProviderConfigs(config); + + expect(providerConfigs).toHaveLength(1); + expect(providerConfigs[0].id).toEqual('default'); + expect(providerConfigs[0].organization).toEqual('test-org'); + }); + + it('multiple provider configs', () => { + const config = new ConfigReader({ + catalog: { + providers: { + github: { + providerOrganizationOnly: { + organization: 'test-org1', + }, + providerCustomCatalogPath: { + organization: 'test-org2', + catalogPath: 'custom/path/catalog-info.yaml', + }, + providerWithRepositoryFilter: { + organization: 'test-org3', + filters: { + repository: 'repository.*filter', + }, + }, + providerWithBranchFilter: { + organization: 'test-org4', + filters: { + branch: 'branch-name', + }, + }, + }, + }, + }, + }); + const providerConfigs = readProviderConfigs(config); + + expect(providerConfigs).toHaveLength(4); + expect(providerConfigs[0]).toEqual({ + id: 'providerOrganizationOnly', + organization: 'test-org1', + catalogPath: '/catalog-info.yaml', + filters: { + repository: undefined, + branch: undefined, + }, + }); + expect(providerConfigs[1]).toEqual({ + id: 'providerCustomCatalogPath', + organization: 'test-org2', + catalogPath: 'custom/path/catalog-info.yaml', + filters: { + repository: undefined, + branch: undefined, + }, + }); + expect(providerConfigs[2]).toEqual({ + id: 'providerWithRepositoryFilter', + organization: 'test-org3', // organization + catalogPath: '/catalog-info.yaml', // file + filters: { + repository: /^repository.*filter$/, // repo + branch: undefined, // branch + }, + }); + expect(providerConfigs[3]).toEqual({ + id: 'providerWithBranchFilter', + organization: 'test-org4', + catalogPath: '/catalog-info.yaml', + filters: { + repository: undefined, + branch: 'branch-name', + }, + }); + }); +}); diff --git a/plugins/catalog-backend-module-github/src/providers/GitHubEntityProviderConfig.ts b/plugins/catalog-backend-module-github/src/providers/GitHubEntityProviderConfig.ts new file mode 100644 index 0000000000..b5929c5300 --- /dev/null +++ b/plugins/catalog-backend-module-github/src/providers/GitHubEntityProviderConfig.ts @@ -0,0 +1,90 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Config } from '@backstage/config'; + +const DEFAULT_CATALOG_PATH = '/catalog-info.yaml'; +const DEFAULT_PROVIDER_ID = 'default'; + +export type GitHubEntityProviderConfig = { + id: string; + catalogPath: string; + organization: string; + filters?: { + repository?: RegExp; + branch?: string; + }; +}; + +export function readProviderConfigs( + config: Config, +): GitHubEntityProviderConfig[] { + const providersConfig = config.getOptionalConfig('catalog.providers.github'); + if (!providersConfig) { + return []; + } + + if (providersConfig.has('organization')) { + // simple/single config variant + return [readProviderConfig(DEFAULT_PROVIDER_ID, providersConfig)]; + } + + return providersConfig.keys().map(id => { + const providerConfig = providersConfig.getConfig(id); + + return readProviderConfig(id, providerConfig); + }); +} + +function readProviderConfig( + id: string, + config: Config, +): GitHubEntityProviderConfig { + const organization = config.getString('organization'); + const catalogPath = + config.getOptionalString('catalogPath') ?? DEFAULT_CATALOG_PATH; + const repositoryPattern = config.getOptionalString('filters.repository'); + const branchPattern = config.getOptionalString('filters.branch'); + + return { + id, + catalogPath, + organization, + filters: { + repository: repositoryPattern + ? compileRegExp(repositoryPattern) + : undefined, + branch: branchPattern || undefined, + }, + }; +} +/** + * Compiles a RegExp while enforcing the pattern to contain + * the start-of-line and end-of-line anchors. + * + * @param pattern + */ +function compileRegExp(pattern: string): RegExp { + let fullLinePattern = pattern; + if (!fullLinePattern.startsWith('^')) { + fullLinePattern = `^${fullLinePattern}`; + } + if (!fullLinePattern.endsWith('$')) { + fullLinePattern = `${fullLinePattern}$`; + } + + return new RegExp(fullLinePattern); +} diff --git a/plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.test.ts b/plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.test.ts similarity index 100% rename from plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.test.ts rename to plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.test.ts diff --git a/plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.ts b/plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts similarity index 99% rename from plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.ts rename to plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts index e6cb413a6f..bb994c193c 100644 --- a/plugins/catalog-backend-module-github/src/GitHubOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-github/src/providers/GitHubOrgEntityProvider.ts @@ -42,7 +42,7 @@ import { getOrganizationTeams, getOrganizationUsers, parseGitHubOrgUrl, -} from './lib'; +} from '../lib'; /** * Options for {@link GitHubOrgEntityProvider}. diff --git a/plugins/catalog-backend-module-gitlab/CHANGELOG.md b/plugins/catalog-backend-module-gitlab/CHANGELOG.md index 0edbae31c4..e3f269514b 100644 --- a/plugins/catalog-backend-module-gitlab/CHANGELOG.md +++ b/plugins/catalog-backend-module-gitlab/CHANGELOG.md @@ -1,5 +1,86 @@ # @backstage/plugin-catalog-backend-module-gitlab +## 0.1.6 + +### Patch Changes + +- 24979413a4: Enhancing GitLab provider with filtering projects by pattern RegExp + + ```yaml + providers: + gitlab: + stg: + host: gitlab.stg.company.io + branch: main + projectPattern: 'john/' # new option + entityFilename: template.yaml + ``` + + With the aforementioned parameter you can filter projects, and keep only who belongs to the namespace "john". + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## 0.1.6-next.1 + +### Patch Changes + +- 24979413a4: Enhancing GitLab provider with filtering projects by pattern RegExp + + ```yaml + providers: + gitlab: + stg: + host: gitlab.stg.company.io + branch: main + projectPattern: 'john/' # new option + entityFilename: template.yaml + ``` + + With the aforementioned parameter you can filter projects, and keep only who belongs to the namespace "john". + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.1-next.2 + +## 0.1.6-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## 0.1.5 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 49ff472c0b: Add the possibility in the `GitlabDiscoveryEntityProvider` to scan the whole project instead of concrete groups. For that, use a configuration like this one, where the group parameter is omitted (not mandatory anymore): + + ```yaml + catalog: + providers: + gitlab: + yourProviderId: + host: gitlab-host # Identifies one of the hosts set up in the integrations + branch: main # Optional. Uses `master` as default + entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml` + ``` + +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + ## 0.1.5-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-gitlab/package.json b/plugins/catalog-backend-module-gitlab/package.json index 800cb8b280..d06cc6f429 100644 --- a/plugins/catalog-backend-module-gitlab/package.json +++ b/plugins/catalog-backend-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-gitlab", "description": "A Backstage catalog backend module that helps integrate towards GitLab", - "version": "0.1.5-next.2", + "version": "0.1.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,23 +33,23 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/backend-tasks": "^0.3.3-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-model": "^1.1.0", + "@backstage/backend-tasks": "^0.3.4", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-backend": "^1.3.1", "@backstage/types": "^1.0.0", "lodash": "^4.17.21", - "msw": "^0.44.0", + "msw": "^0.45.0", "node-fetch": "^2.6.7", "winston": "^3.2.1", "uuid": "^8.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "@types/lodash": "^4.14.151", "@types/uuid": "^8.0.0" }, diff --git a/plugins/catalog-backend-module-gitlab/src/lib/types.ts b/plugins/catalog-backend-module-gitlab/src/lib/types.ts index 69de9d28c7..8a3c33c8f2 100644 --- a/plugins/catalog-backend-module-gitlab/src/lib/types.ts +++ b/plugins/catalog-backend-module-gitlab/src/lib/types.ts @@ -35,4 +35,5 @@ export type GitlabProviderConfig = { id: string; branch: string; catalogFile: string; + projectPattern: RegExp; }; diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts index dc70772d3d..d4a13cf81e 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.test.ts @@ -227,4 +227,113 @@ describe('GitlabDiscoveryEntityProvider', () => { entities: expectedEntities, }); }); + + it('should filter found projects based on a provided project pattern', async () => { + const config = new ConfigReader({ + integrations: { + gitlab: [ + { + host: 'test-gitlab', + apiBaseUrl: 'https://api.gitlab.example/api/v4', + token: '1234', + }, + ], + }, + catalog: { + providers: { + gitlab: { + 'test-id': { + host: 'test-gitlab', + projectPattern: 'john/', + }, + }, + }, + }, + }); + const schedule = new PersistingTaskRunner(); + const entityProviderConnection: EntityProviderConnection = { + applyMutation: jest.fn(), + }; + const provider = GitlabDiscoveryEntityProvider.fromConfig(config, { + logger, + schedule, + })[0]; + + server.use( + rest.get( + `https://api.gitlab.example/api/v4/projects`, + (_req, res, ctx) => { + const response = [ + { + id: 123, + default_branch: 'master', + archived: false, + last_activity_at: new Date().toString(), + web_url: 'https://api.gitlab.example/test-group/test-repo', + path_with_namespace: 'test-group/test-repo', + }, + { + id: 124, + default_branch: 'master', + archived: false, + last_activity_at: new Date().toString(), + web_url: 'https://api.gitlab.example/john/example', + path_with_namespace: 'john/example', + }, + ]; + return res(ctx.json(response)); + }, + ), + rest.head( + 'https://api.gitlab.example/api/v4/projects/test-group%2Ftest-repo/repository/files/catalog-info.yaml', + (req, res, ctx) => { + if (req.url.searchParams.get('ref') === 'master') { + return res(ctx.status(200)); + } + return res(ctx.status(404, 'Not Found')); + }, + ), + rest.head( + 'https://api.gitlab.example/api/v4/projects/john%2Fexample/repository/files/catalog-info.yaml', + (req, res, ctx) => { + if (req.url.searchParams.get('ref') === 'master') { + return res(ctx.status(200)); + } + return res(ctx.status(404, 'Not Found')); + }, + ), + ); + + await provider.connect(entityProviderConnection); + + await provider.refresh(logger); + + expect(entityProviderConnection.applyMutation).toBeCalledWith({ + type: 'full', + entities: [ + { + entity: { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Location', + metadata: { + annotations: { + 'backstage.io/managed-by-location': + 'url:https://api.gitlab.example/john/example/-/blob/master/catalog-info.yaml', + 'backstage.io/managed-by-origin-location': + 'url:https://api.gitlab.example/john/example/-/blob/master/catalog-info.yaml', + }, + name: 'generated-2045212e5b3e9e6bacf51cec709e362282e3cda9', + }, + spec: { + presence: 'optional', + target: + 'https://api.gitlab.example/john/example/-/blob/master/catalog-info.yaml', + type: 'url', + }, + }, + locationKey: 'GitlabDiscoveryEntityProvider:test-id', + }, + ], + }); + }); }); diff --git a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts index 36c3ee90be..ffb123edf7 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/GitlabDiscoveryEntityProvider.ts @@ -147,6 +147,10 @@ export class GitlabDiscoveryEntityProvider implements EntityProvider { }; for await (const project of projects) { + if (!this.config.projectPattern.test(project.path_with_namespace ?? '')) { + continue; + } + res.scanned++; if (project.archived) { diff --git a/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts b/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts index 892ce5f25c..cb36e5166c 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/config.test.ts @@ -52,6 +52,7 @@ describe('config', () => { branch: 'master', host: 'host', catalogFile: 'catalog-info.yaml', + projectPattern: /[\s\S]*/, }), ); }); @@ -81,6 +82,7 @@ describe('config', () => { branch: 'not-master', host: 'host', catalogFile: 'custom-file.yaml', + projectPattern: /[\s\S]*/, }), ); }); diff --git a/plugins/catalog-backend-module-gitlab/src/providers/config.ts b/plugins/catalog-backend-module-gitlab/src/providers/config.ts index d6ad28b2ca..392922860f 100644 --- a/plugins/catalog-backend-module-gitlab/src/providers/config.ts +++ b/plugins/catalog-backend-module-gitlab/src/providers/config.ts @@ -15,13 +15,14 @@ */ import { Config } from '@backstage/config'; -import { GitlabProviderConfig } from '../lib/types'; +import { GitlabProviderConfig } from '../lib'; /** * Extracts the gitlab config from a config object * * @public * + * @param id - The provider key * @param config - The config object to extract from */ function readGitlabConfig(id: string, config: Config): GitlabProviderConfig { @@ -30,6 +31,9 @@ function readGitlabConfig(id: string, config: Config): GitlabProviderConfig { const branch = config.getOptionalString('branch') ?? 'master'; const catalogFile = config.getOptionalString('entityFilename') ?? 'catalog-info.yaml'; + const projectPattern = new RegExp( + config.getOptionalString('projectPattern') ?? /[\s\S]*/, + ); return { id, @@ -37,6 +41,7 @@ function readGitlabConfig(id: string, config: Config): GitlabProviderConfig { branch, host, catalogFile, + projectPattern, }; } diff --git a/plugins/catalog-backend-module-ldap/CHANGELOG.md b/plugins/catalog-backend-module-ldap/CHANGELOG.md index 5d65d1c768..8e41d6325b 100644 --- a/plugins/catalog-backend-module-ldap/CHANGELOG.md +++ b/plugins/catalog-backend-module-ldap/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-catalog-backend-module-ldap +## 0.5.2 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## 0.5.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## 0.5.1 + +### Patch Changes + +- ddfd566606: Fix mapping between users and groups for FreeIPA when using the LdapOrgProcessor +- fbfbff6bf7: Add possibility to resolve relations by RDN, in addition to UUID and DN +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/catalog-model@1.1.0 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + ## 0.5.1-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-ldap/api-report.md b/plugins/catalog-backend-module-ldap/api-report.md index 90e58b3fb2..9876c163e8 100644 --- a/plugins/catalog-backend-module-ldap/api-report.md +++ b/plugins/catalog-backend-module-ldap/api-report.md @@ -90,7 +90,7 @@ export class LdapClient { searchStreaming( dn: string, options: SearchOptions, - f: (entry: SearchEntry) => void, + f: (entry: SearchEntry) => Promise | void, ): Promise; } diff --git a/plugins/catalog-backend-module-ldap/package.json b/plugins/catalog-backend-module-ldap/package.json index b89382977a..1de6cbd331 100644 --- a/plugins/catalog-backend-module-ldap/package.json +++ b/plugins/catalog-backend-module-ldap/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-ldap", "description": "A Backstage catalog backend module that helps integrate towards LDAP", - "version": "0.5.1-next.2", + "version": "0.5.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,11 +33,11 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-tasks": "^0.3.3-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-tasks": "^0.3.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-catalog-backend": "^1.3.1", "@backstage/types": "^1.0.0", "@types/ldapjs": "^2.2.0", "ldapjs": "^2.2.0", @@ -46,7 +46,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/lodash": "^4.14.151" }, "files": [ diff --git a/plugins/catalog-backend-module-ldap/src/ldap/client.ts b/plugins/catalog-backend-module-ldap/src/ldap/client.ts index d9d0faf9a2..0afeb16248 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/client.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/client.ts @@ -14,12 +14,12 @@ * limitations under the License. */ -import { ForwardedError } from '@backstage/errors'; +import { ForwardedError, stringifyError } from '@backstage/errors'; import ldap, { Client, SearchEntry, SearchOptions } from 'ldapjs'; import { cloneDeep } from 'lodash'; import { Logger } from 'winston'; import { BindConfig, TLSConfig } from './config'; -import { errorString } from './util'; +import { createOptions, errorString } from './util'; import { ActiveDirectoryVendor, DefaultLdapVendor, @@ -147,23 +147,45 @@ export class LdapClient { async searchStreaming( dn: string, options: SearchOptions, - f: (entry: SearchEntry) => void, + f: (entry: SearchEntry) => Promise | void, ): Promise { try { return await new Promise((resolve, reject) => { // Note that we clone the (frozen) options, since ldapjs rudely tries to // overwrite parts of them - this.client.search(dn, cloneDeep(options), (err, res) => { + this.client.search(dn, createOptions(options), (err, res) => { if (err) { reject(new Error(errorString(err))); } + let awaitList: Array | void> = []; + let transformError = false; + + const transformReject = (e: Error) => { + transformError = true; + reject( + new Error( + `Transform function threw an exception, ${stringifyError(e)}`, + ), + ); + }; res.on('searchReference', () => { this.logger.warn('Received unsupported search referral'); }); res.on('searchEntry', entry => { - f(entry); + if (!transformError) awaitList.push(f(entry)); + }); + + res.on('page', (_, cb) => { + // awaits completion before fetching next page + Promise.all(awaitList) + .then(() => { + // flush list + awaitList = []; + if (cb) cb(); + }) + .catch(transformReject); }); res.on('error', e => { @@ -176,7 +198,9 @@ export class LdapClient { } else if (r.status !== 0) { throw new Error(`Got status ${r.status}: ${r.errorMessage}`); } else { - resolve(); + Promise.all(awaitList) + .then(() => resolve()) + .catch(transformReject); } }); }); diff --git a/plugins/catalog-backend-module-ldap/src/ldap/util.test.ts b/plugins/catalog-backend-module-ldap/src/ldap/util.test.ts index 5978012875..d8787b1226 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/util.test.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/util.test.ts @@ -14,7 +14,7 @@ * limitations under the License. */ -import { errorString } from './util'; +import { errorString, createOptions } from './util'; describe('errorString', () => { it('formats', () => { @@ -22,3 +22,52 @@ describe('errorString', () => { expect(errorString(e)).toEqual('1 n: m'); }); }); + +describe('createOptions', () => { + it('should add pagePause', () => { + const options = { + filter: 'f', + paged: true, + timeLimit: 42, + sizeLimit: 100, + derefAliases: 0, + typesOnly: false, + }; + expect(createOptions(options)).toEqual({ + filter: 'f', + paged: { pagePause: true }, + timeLimit: 42, + sizeLimit: 100, + derefAliases: 0, + typesOnly: false, + }); + const options2 = { + filter: 'f', + paged: {}, + timeLimit: 42, + sizeLimit: 100, + derefAliases: 0, + typesOnly: false, + }; + expect(createOptions(options2)).toEqual({ + filter: 'f', + paged: { pagePause: true }, + timeLimit: 42, + sizeLimit: 100, + derefAliases: 0, + typesOnly: false, + }); + }); + + it('should not add pagePause', () => { + const options = { + filter: 'f', + paged: false, + timeLimit: 42, + sizeLimit: 100, + derefAliases: 0, + typesOnly: false, + }; + expect(createOptions(options)).toEqual(options); + }); +}); diff --git a/plugins/catalog-backend-module-ldap/src/ldap/util.ts b/plugins/catalog-backend-module-ldap/src/ldap/util.ts index 0f443c1a86..74b8fe4f88 100644 --- a/plugins/catalog-backend-module-ldap/src/ldap/util.ts +++ b/plugins/catalog-backend-module-ldap/src/ldap/util.ts @@ -14,7 +14,8 @@ * limitations under the License. */ -import { Error as LDAPError, SearchEntry } from 'ldapjs'; +import { Error as LDAPError, SearchEntry, SearchOptions } from 'ldapjs'; +import { cloneDeep } from 'lodash'; import { LdapVendor } from './vendors'; /** @@ -54,6 +55,18 @@ export function mapStringAttr( } } +export function createOptions(inputOptions: SearchOptions): SearchOptions { + const result = cloneDeep(inputOptions); + + if (result.paged === true) { + result.paged = { pagePause: true }; + } else if (typeof result.paged === 'object') { + result.paged.pagePause = true; + } + + return result; +} + export type RecursivePartial = { [P in keyof T]?: T[P] extends (infer U)[] ? RecursivePartial[] diff --git a/plugins/catalog-backend-module-msgraph/CHANGELOG.md b/plugins/catalog-backend-module-msgraph/CHANGELOG.md index 43ee7ff4f5..f914f83f00 100644 --- a/plugins/catalog-backend-module-msgraph/CHANGELOG.md +++ b/plugins/catalog-backend-module-msgraph/CHANGELOG.md @@ -1,5 +1,132 @@ # @backstage/plugin-catalog-backend-module-msgraph +## 0.4.1 + +### Patch Changes + +- b1995df9f3: Adjust references in deprecation warnings to point to stable URL/document. +- Updated dependencies + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-catalog-backend@1.3.1 + +## 0.4.1-next.0 + +### Patch Changes + +- b1995df9f3: Adjust references in deprecation warnings to point to stable URL/document. +- Updated dependencies + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## 0.4.0 + +### Minor Changes + +- a145672f0f: Align `msgraph` plugin's entity provider config with other providers. **Deprecated** entity processor as well as previous config. + + You will see warning at the log output until you migrate to the new setup. + All deprecated parts will be removed eventually after giving some time to migrate. + + Please find information on how to migrate your current setup to the new one below. + + **Migration Guide:** + + There were two different way on how to use the msgraph plugin: processor or provider. + + Previous registration for the processor: + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addProcessor( + MicrosoftGraphOrgReaderProcessor.fromConfig(env.config, { + logger: env.logger, + // [...] + }), + ); + ``` + + Previous registration when using the provider: + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addEntityProvider( + MicrosoftGraphOrgEntityProvider.fromConfig(env.config, { + id: 'https://graph.microsoft.com/v1.0', + target: 'https://graph.microsoft.com/v1.0', + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + // [...] + }), + ); + ``` + + Previous configuration as used for both: + + ```yaml + # app-config.yaml + catalog: + processors: + microsoftGraphOrg: + providers: + - target: https://graph.microsoft.com/v1.0 + # [...] + ``` + + **Replacement:** + + Please check https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-msgraph/README.md for the complete documentation of all configuration options (config as well as registration of the provider). + + ```yaml + # app-config.yaml + catalog: + providers: + microsoftGraphOrg: + # In case you used the deprecated configuration with the entity provider + # using the value of `target` will keep the same location key for all + providerId: # some stable ID which will be used as part of the location key for all ingested data + target: https://graph.microsoft.com/v1.0 + # [...] + ``` + + ```typescript + // packages/backend/src/plugins/catalog.ts + builder.addEntityProvider( + MicrosoftGraphOrgEntityProvider.fromConfig(env.config, { + logger: env.logger, + schedule: env.scheduler.createScheduledTaskRunner({ + frequency: { minutes: 30 }, + timeout: { minutes: 3 }, + }), + // [...] + }), + ); + ``` + + In case you've used multiple entity providers before + **and** you had different transformers for each of them + you can provide these directly at the one `fromConfig` call + by passing a Record with the provider ID as key. + +- b8ebecd100: Microsoft Graph plugin can supports many more options for authenticating with the Microsoft Graph API. + Previously only ClientId/ClientSecret was supported, but now all the authentication options of `DefaultAzureCredential` from `@azure/identity` are supported. + Including Managed Identity, Client Certificate, Azure CLI and VS Code. + + If `clientId` and `clientSecret` are specified in configuration, the plugin behaves the same way as before. + If these fields are omitted, the plugin uses `DefaultAzureCredential` to automatically determine the best authentication method. + This is particularly useful for local development environments - the default configuration will try to use existing credentials from Visual Studio Code, Azure CLI and Azure PowerShell, without the user needing to configure any credentials in app-config.yaml + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/catalog-model@1.1.0 + - @backstage/backend-tasks@0.3.3 + ## 0.4.0-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-msgraph/README.md b/plugins/catalog-backend-module-msgraph/README.md index 23166a755d..fe2e568b5a 100644 --- a/plugins/catalog-backend-module-msgraph/README.md +++ b/plugins/catalog-backend-module-msgraph/README.md @@ -80,7 +80,7 @@ catalog: # See https://docs.microsoft.com/en-us/graph/search-query-parameter search: '"description:One" AND ("displayName:Video" OR "displayName:Drive")' # Optional select for groups, this will allow you work with schemaExtensions - # in order to add extra information to your groups that can be used on you custom groupTransformers + # in order to add extra information to your groups that can be used on your custom groupTransformers # See https://docs.microsoft.com/en-us/graph/api/resources/schemaextension?view=graph-rest-1.0 select: ['id', 'displayName', 'description'] ``` diff --git a/plugins/catalog-backend-module-msgraph/package.json b/plugins/catalog-backend-module-msgraph/package.json index a411974bd6..c12f1bfaf5 100644 --- a/plugins/catalog-backend-module-msgraph/package.json +++ b/plugins/catalog-backend-module-msgraph/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-msgraph", "description": "A Backstage catalog backend module that helps integrate towards Microsoft Graph", - "version": "0.4.0-next.2", + "version": "0.4.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,10 +34,10 @@ }, "dependencies": { "@azure/identity": "^2.1.0", - "@backstage/backend-tasks": "^0.3.3-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-tasks": "^0.3.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", + "@backstage/plugin-catalog-backend": "^1.3.1", "@microsoft/microsoft-graph-types": "^2.6.0", "@types/node-fetch": "^2.5.12", "lodash": "^4.17.21", @@ -48,11 +48,11 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "@types/lodash": "^4.14.151", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts index 4a52ddc665..4c38198b0d 100644 --- a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts +++ b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgEntityProvider.ts @@ -211,7 +211,7 @@ export class MicrosoftGraphOrgEntityProvider implements EntityProvider { options: MicrosoftGraphOrgEntityProviderLegacyOptions, ): MicrosoftGraphOrgEntityProvider { options.logger.warn( - 'Deprecated msgraph config "catalog.processors.microsoftGraphOrg" used. Use "catalog.providers.microsoftGraphOrg" instead. More info at https://github.com/backstage/backstage/blob/master/.changeset/long-bananas-rescue.md', + 'Deprecated msgraph config "catalog.processors.microsoftGraphOrg" used. Use "catalog.providers.microsoftGraphOrg" instead. More info at https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-msgraph/CHANGELOG.md#040-next1', ); const config = configRoot.getOptionalConfig( 'catalog.processors.microsoftGraphOrg', diff --git a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts index decd84ec1f..1267648481 100644 --- a/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts +++ b/plugins/catalog-backend-module-msgraph/src/processors/MicrosoftGraphOrgReaderProcessor.ts @@ -69,7 +69,7 @@ export class MicrosoftGraphOrgReaderProcessor implements CatalogProcessor { organizationTransformer?: OrganizationTransformer; }) { options.logger.warn( - 'MicrosoftGraphOrgReaderProcessor is deprecated. Please use MicrosoftGraphOrgEntityProvider instead. More info at https://github.com/backstage/backstage/blob/master/.changeset/long-bananas-rescue.md', + 'MicrosoftGraphOrgReaderProcessor is deprecated. Please use MicrosoftGraphOrgEntityProvider instead. More info at https://github.com/backstage/backstage/blob/master/plugins/catalog-backend-module-msgraph/CHANGELOG.md#040-next1', ); this.providers = options.providers; this.logger = options.logger; diff --git a/plugins/catalog-backend-module-openapi/CHANGELOG.md b/plugins/catalog-backend-module-openapi/CHANGELOG.md index c2de74bfc4..660fbd4148 100644 --- a/plugins/catalog-backend-module-openapi/CHANGELOG.md +++ b/plugins/catalog-backend-module-openapi/CHANGELOG.md @@ -1,5 +1,59 @@ # @backstage/plugin-catalog-backend-module-openapi +## 0.1.1 + +### Patch Changes + +- b50e8e533b: Add an `$openapi` placeholder resolver that supports more use cases for resolving `$ref` instances. This means that the quite recently added `OpenApiRefProcessor` has been deprecated in favor of the `openApiPlaceholderResolver`. + + An example of how to use it can be seen below. + + ```yaml + apiVersion: backstage.io/v1alpha1 + kind: API + metadata: + name: example + description: Example API + spec: + type: openapi + lifecycle: production + owner: team + definition: + $openapi: ./spec/openapi.yaml # by using $openapi Backstage will now resolve all $ref instances + ``` + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-catalog-node@1.0.1 + - @backstage/integration@1.3.0 + - @backstage/plugin-catalog-backend@1.3.1 + +## 0.1.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-catalog-backend@1.3.1-next.0 + +## 0.1.0 + +### Minor Changes + +- 67503d159e: Add basic OpenAPI \$ref support. + + For more information see [here](https://github.com/backstage/backstage/tree/master/plugins/catalog-backend-module-openapi). + +### Patch Changes + +- 4881dc4c84: Updated dependency `openapi-types` to `^12.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-backend@1.3.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + ## 0.1.0-next.2 ### Patch Changes diff --git a/plugins/catalog-backend-module-openapi/README.md b/plugins/catalog-backend-module-openapi/README.md index 1a133521c6..f80798e267 100644 --- a/plugins/catalog-backend-module-openapi/README.md +++ b/plugins/catalog-backend-module-openapi/README.md @@ -15,6 +15,32 @@ yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-openapi ### Adding the plugin to your `packages/backend` +#### **openApiPlaceholderResolver** + +The placeholder resolver can be added by importing `openApiPlaceholderResolver` in `src/plugins/catalog.ts` in your `backend` package and adding the following. + +```ts +builder.setPlaceholderResolver('openapi', openApiPlaceholderResolver); +``` + +This allows you to use the `$openapi` placeholder when referencing your OpenAPI specification. This will then resolve all `$ref` instances in your specification. + +```yaml +apiVersion: backstage.io/v1alpha1 +kind: API +metadata: + name: example + description: Example API +spec: + type: openapi + lifecycle: production + owner: team + definition: + $openapi: ./spec/openapi.yaml # by using $openapi Backstage will now resolve all $ref instances +``` + +#### **OpenAPIRefProcessor** (deprecated) + The processor can be added by importing `OpenApiRefProcessor` in `src/plugins/catalog.ts` in your `backend` package and adding the following. ```ts diff --git a/plugins/catalog-backend-module-openapi/api-report.md b/plugins/catalog-backend-module-openapi/api-report.md index 92ddd1e3cd..d3a40067c5 100644 --- a/plugins/catalog-backend-module-openapi/api-report.md +++ b/plugins/catalog-backend-module-openapi/api-report.md @@ -6,12 +6,19 @@ import { CatalogProcessor } from '@backstage/plugin-catalog-backend'; import { Config } from '@backstage/config'; import { Entity } from '@backstage/catalog-model'; +import { JsonValue } from '@backstage/types'; import { LocationSpec } from '@backstage/plugin-catalog-backend'; import { Logger } from 'winston'; +import { PlaceholderResolverParams } from '@backstage/plugin-catalog-backend'; import { ScmIntegrations } from '@backstage/integration'; import { UrlReader } from '@backstage/backend-common'; // @public (undocumented) +export function openApiPlaceholderResolver( + params: PlaceholderResolverParams, +): Promise; + +// @public @deprecated (undocumented) export class OpenApiRefProcessor implements CatalogProcessor { constructor(options: { integrations: ScmIntegrations; diff --git a/plugins/catalog-backend-module-openapi/package.json b/plugins/catalog-backend-module-openapi/package.json index 82fc1c03e4..ce08fcf4d3 100644 --- a/plugins/catalog-backend-module-openapi/package.json +++ b/plugins/catalog-backend-module-openapi/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend-module-openapi", "description": "A Backstage catalog backend module that helps with OpenAPI specifications", - "version": "0.1.0-next.2", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,17 +34,19 @@ }, "dependencies": { "@apidevtools/swagger-parser": "^10.1.0", - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-catalog-backend": "^1.3.0-next.3", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-backend": "^1.3.1", + "@backstage/plugin-catalog-node": "^1.0.1", + "@backstage/types": "^1.0.0", "winston": "^3.2.1", "yaml": "^2.1.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", "openapi-types": "^12.0.0" }, "files": [ diff --git a/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.test.ts b/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.test.ts index 8f2cc571c2..21080202b5 100644 --- a/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.test.ts +++ b/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.test.ts @@ -86,7 +86,7 @@ describe('OpenApiRefProcessor', () => { it('should ignore other specification types', async () => { const { entity, processor } = setupTest({ - kind: 'Group', + kind: 'API', spec: { type: 'asyncapi' }, }); diff --git a/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.ts b/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.ts index 01875e0779..f4cffdf48f 100644 --- a/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.ts +++ b/plugins/catalog-backend-module-openapi/src/OpenApiRefProcessor.ts @@ -24,7 +24,10 @@ import { import { bundleOpenApiSpecification } from './lib'; import { Logger } from 'winston'; -/** @public */ +/** + * @public + * @deprecated replaced by the openApiPlaceholderResolver + */ export class OpenApiRefProcessor implements CatalogProcessor { private readonly integrations: ScmIntegrations; private readonly logger: Logger; @@ -69,17 +72,23 @@ export class OpenApiRefProcessor implements CatalogProcessor { } const scmIntegration = this.integrations.byUrl(location.target); - if (!scmIntegration) { + const definition = entity.spec!.definition; + + if (!scmIntegration || !definition) { return entity; } + const resolveUrl = (url: string, base: string): string => { + return scmIntegration.resolveUrl({ url, base }); + }; + this.logger.debug(`Bundling OpenAPI specification from ${location.target}`); try { const bundledSpec = await bundleOpenApiSpecification( - entity.spec!.definition?.toString(), + definition.toString(), location.target, - this.reader, - scmIntegration, + this.reader.read, + resolveUrl, ); return { diff --git a/plugins/catalog-backend-module-openapi/src/index.ts b/plugins/catalog-backend-module-openapi/src/index.ts index f98bee6bac..ccd3ced71e 100644 --- a/plugins/catalog-backend-module-openapi/src/index.ts +++ b/plugins/catalog-backend-module-openapi/src/index.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export { OpenApiRefProcessor } from './OpenApiRefProcessor'; +export { openApiPlaceholderResolver } from './openApiPlaceholderResolver'; diff --git a/plugins/catalog-backend-module-openapi/src/lib/bundle.test.ts b/plugins/catalog-backend-module-openapi/src/lib/bundle.test.ts index 4505f158b5..0ecd9f7fd1 100644 --- a/plugins/catalog-backend-module-openapi/src/lib/bundle.test.ts +++ b/plugins/catalog-backend-module-openapi/src/lib/bundle.test.ts @@ -13,8 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { ConfigReader } from '@backstage/config'; -import { ScmIntegrations } from '@backstage/integration'; import { bundleOpenApiSpecification } from './bundle'; const specification = ` @@ -73,43 +71,21 @@ paths: `; describe('bundleOpenApiSpecification', () => { - const readUrl = jest.fn(); - const reader = { - readUrl, - read: jest.fn(), - readTree: jest.fn(), - search: jest.fn(), - }; - - const scmIntegration = ScmIntegrations.fromConfig(new ConfigReader({})).byUrl( - 'https://github.com/owner/repo/blob/main/openapi.yaml', - ); + const read = jest.fn(); + const resolveUrl = jest.fn(); beforeEach(() => { jest.clearAllMocks(); }); - it('should return undefined if no specification is supplied', async () => { - expect( - await bundleOpenApiSpecification( - undefined, - 'https://github.com/owner/repo/blob/main/openapi.yaml', - reader, - scmIntegration as any, - ), - ).toBeUndefined(); - }); - it('should return the bundled specification', async () => { - readUrl.mockResolvedValue({ - buffer: jest.fn().mockResolvedValue(list), - }); + read.mockResolvedValue(list); const result = await bundleOpenApiSpecification( specification, - 'https://github.com/owner/repo/blob/main/openapi.yaml', - reader, - scmIntegration as any, + 'https://github.com/owner/repo/blob/main/catalog-info.yaml', + read, + resolveUrl, ); expect(result).toEqual(expectedResult.trimStart()); diff --git a/plugins/catalog-backend-module-openapi/src/lib/bundle.ts b/plugins/catalog-backend-module-openapi/src/lib/bundle.ts index 3d35429d8b..6ac8d211e2 100644 --- a/plugins/catalog-backend-module-openapi/src/lib/bundle.ts +++ b/plugins/catalog-backend-module-openapi/src/lib/bundle.ts @@ -13,8 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { UrlReader } from '@backstage/backend-common'; -import { ScmIntegration } from '@backstage/integration'; import SwaggerParser from '@apidevtools/swagger-parser'; import { parse, stringify } from 'yaml'; import * as path from 'path'; @@ -28,12 +26,16 @@ const getProtocol = (refPath: string) => { return undefined; }; +export type BundlerRead = (url: string) => Promise; + +export type BundlerResolveUrl = (url: string, base: string) => string; + export async function bundleOpenApiSpecification( - specification: string | undefined, - targetUrl: string, - reader: UrlReader, - scmIntegration: ScmIntegration, -): Promise { + specification: string, + baseUrl: string, + read: BundlerRead, + resolveUrl: BundlerResolveUrl, +): Promise { const fileUrlReaderResolver: SwaggerParser.ResolverOptions = { canRead: file => { const protocol = getProtocol(file.url); @@ -41,22 +43,11 @@ export async function bundleOpenApiSpecification( }, read: async file => { const relativePath = path.relative('.', file.url); - const url = scmIntegration.resolveUrl({ - base: targetUrl, - url: relativePath, - }); - if (reader.readUrl) { - const data = await reader.readUrl(url); - return data.buffer(); - } - throw new Error('UrlReader has no readUrl method defined'); + const url = resolveUrl(relativePath, baseUrl); + return await read(url); }, }; - if (!specification) { - return undefined; - } - const options: SwaggerParser.Options = { resolve: { file: fileUrlReaderResolver, diff --git a/plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.test.ts b/plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.test.ts new file mode 100644 index 0000000000..f58a818ba5 --- /dev/null +++ b/plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.test.ts @@ -0,0 +1,63 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { PlaceholderResolverParams } from '@backstage/plugin-catalog-backend'; +import { openApiPlaceholderResolver } from './openApiPlaceholderResolver'; +import { bundleOpenApiSpecification } from './lib'; + +jest.mock('./lib', () => ({ + bundleOpenApiSpecification: jest.fn(), +})); + +const bundledSpecification = ''; + +describe('openApiPlaceholderResolver', () => { + const mockResolveUrl = jest.fn(); + mockResolveUrl.mockReturnValue('mockUrl'); + + const mockRead = jest.fn(); + mockRead.mockResolvedValue(Buffer.from('mockData')); + + const params: PlaceholderResolverParams = { + key: 'openapi', + value: './spec/openapi.yaml', + baseUrl: 'https://github.com/owner/repo/blob/main/catalog-info.yaml', + resolveUrl: mockResolveUrl, + read: mockRead, + emit: jest.fn(), + }; + + beforeEach(() => { + (bundleOpenApiSpecification as any).mockResolvedValue(bundledSpecification); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should throw error if unable to bundle the OpenAPI specification', async () => { + (bundleOpenApiSpecification as any).mockRejectedValue(new Error('TEST')); + + await expect(openApiPlaceholderResolver(params)).rejects.toThrow( + 'Placeholder $openapi unable to bundle OpenAPI specification', + ); + }); + + it('should bundle the OpenAPI specification', async () => { + const result = await openApiPlaceholderResolver(params); + + expect(result).toEqual(bundledSpecification); + }); +}); diff --git a/plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.ts b/plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.ts new file mode 100644 index 0000000000..96fadb3cbc --- /dev/null +++ b/plugins/catalog-backend-module-openapi/src/openApiPlaceholderResolver.ts @@ -0,0 +1,85 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { PlaceholderResolverParams } from '@backstage/plugin-catalog-backend'; +import { JsonValue } from '@backstage/types'; +import { processingResult } from '@backstage/plugin-catalog-node'; +import { bundleOpenApiSpecification } from './lib'; + +/** @public */ +export async function openApiPlaceholderResolver( + params: PlaceholderResolverParams, +): Promise { + const { content, url } = await readTextLocation(params); + + params.emit(processingResult.refresh(`url:${url}`)); + + try { + return await bundleOpenApiSpecification( + content, + url, + params.read, + params.resolveUrl, + ); + } catch (error) { + throw new Error( + `Placeholder \$${params.key} unable to bundle OpenAPI specification at ${params.value}, ${error}`, + ); + } +} + +/* + * Helpers, copied from PlaceholderProcessor + */ + +async function readTextLocation( + params: PlaceholderResolverParams, +): Promise<{ content: string; url: string }> { + const newUrl = relativeUrl(params); + + try { + const data = await params.read(newUrl); + return { content: data.toString('utf-8'), url: newUrl }; + } catch (e) { + throw new Error( + `Placeholder \$${params.key} could not read location ${params.value}, ${e}`, + ); + } +} + +function relativeUrl({ + key, + value, + baseUrl, + resolveUrl, +}: PlaceholderResolverParams): string { + if (typeof value !== 'string') { + throw new Error( + `Placeholder \$${key} expected a string value parameter, in the form of an absolute URL or a relative path`, + ); + } + + try { + return resolveUrl(value, baseUrl); + } catch (e) { + // The only remaining case that isn't support is a relative file path that should be + // resolved using a relative file location. Accessing local file paths can lead to + // path traversal attacks and access to any file on the host system. Implementing this + // would require additional security measures. + throw new Error( + `Placeholder \$${key} could not form a URL out of ${baseUrl} and ${value}, ${e}`, + ); + } +} diff --git a/plugins/catalog-backend/CHANGELOG.md b/plugins/catalog-backend/CHANGELOG.md index d809c40018..bc287ad98a 100644 --- a/plugins/catalog-backend/CHANGELOG.md +++ b/plugins/catalog-backend/CHANGELOG.md @@ -1,5 +1,120 @@ # @backstage/plugin-catalog-backend +## 1.3.1 + +### Patch Changes + +- 56e1b4b89c: Fixed typos in alpha types. +- e3d3018531: Fix issue for conditional decisions based on properties stored as arrays, like tags. + + Before this change, having a permission policy returning conditional decisions based on metadata like tags, such like `createCatalogConditionalDecision(permission, catalogConditions.hasMetadata('tags', 'java'),)`, was producing wrong results. The issue occurred when authorizing entities already loaded from the database, for example when authorizing `catalogEntityDeletePermission`. + +- 059ae348b4: Use the non-deprecated form of table.unique in knex +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-plugin-api@0.1.1 + - @backstage/plugin-catalog-node@1.0.1 + - @backstage/integration@1.3.0 + - @backstage/plugin-catalog-common@1.0.5 + - @backstage/plugin-permission-node@0.6.4 + +## 1.3.1-next.2 + +### Patch Changes + +- 059ae348b4: Use the non-deprecated form of table.unique in knex + +## 1.3.1-next.1 + +### Patch Changes + +- e3d3018531: Fix issue for conditional decisions based on properties stored as arrays, like tags. + + Before this change, having a permission policy returning conditional decisions based on metadata like tags, such like `createCatalogConditionalDecision(permission, catalogConditions.hasMetadata('tags', 'java'),)`, was producing wrong results. The issue occurred when authorizing entities already loaded from the database, for example when authorizing `catalogEntityDeletePermission`. + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/backend-common@0.15.0-next.1 + - @backstage/integration@1.3.0-next.1 + +## 1.3.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/backend-plugin-api@0.1.1-next.0 + - @backstage/plugin-catalog-node@1.0.1-next.0 + - @backstage/plugin-permission-node@0.6.4-next.0 + +## 1.3.0 + +### Minor Changes + +- 1dd6c22cc8: Added an option to be able to trigger refreshes on entities based on a prestored arbitrary key. + + The UrlReaderProcessor, FileReaderProcessor got updated to store the absolute URL of the catalog file as a refresh key. In the format of `:` + The PlaceholderProcessor got updated to store the resolverValues as refreshKeys for the entities. + + The custom resolvers will need to be updated to pass in a `CatalogProcessorEmit` function as parameter and they should be updated to emit their refresh processingResults. You can see the updated resolvers in the `PlaceholderProcessor.ts` + + ```ts + // yamlPlaceholderResolver + ... + const { content, url } = await readTextLocation(params); + + params.emit(processingResult.refresh(`url:${url}`)); + ... + ``` + +- 91c1d12123: Export experimental `catalogPlugin` for the new backend system. This export is not considered stable and should not be used in production. + +### Patch Changes + +- 1e02fe46d6: Fixed bug where catalog metrics weren't being tracked. +- 5f6b847c15: Fix Error Code in Register Component DryRun +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- fa0533e604: CatalogBuilder supports now subscription to processing engine errors. + + ```ts + subscribe(options: { + onProcessingError: (event: { unprocessedEntity: Entity, error: Error }) => Promise | void; + }); + ``` + + If you want to get notified on errors while processing the entities, you call CatalogBuilder.subscribe + to get notifications with the parameters defined as above. + +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- f1dcc6f3c6: Use entity type predicates from catalog-model +- 9a6aba1d85: Many symbol declarations have been moved to `@backstage/plugin-catalog-node`. This has no affect on users of this package as they are all re-exported. Modules that build on top of the catalog backend plugin should switch all of their imports to the `@backstage/plugin-catalog-node` package and remove the dependency on `@backstage/plugin-catalog-backend`. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/plugin-catalog-node@1.0.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/plugin-permission-node@0.6.3 + - @backstage/errors@1.1.0 + - @backstage/plugin-catalog-common@1.0.4 + - @backstage/plugin-scaffolder-common@1.1.2 + ## 1.3.0-next.3 ### Minor Changes diff --git a/plugins/catalog-backend/api-report.md b/plugins/catalog-backend/api-report.md index 22a7f8192c..55f2d114db 100644 --- a/plugins/catalog-backend/api-report.md +++ b/plugins/catalog-backend/api-report.md @@ -5,7 +5,7 @@ ```ts /// -import { BackendRegistrable } from '@backstage/backend-plugin-api'; +import { BackendFeature } from '@backstage/backend-plugin-api'; import { CatalogApi } from '@backstage/catalog-client'; import { CatalogEntityDocument } from '@backstage/plugin-catalog-common'; import { CatalogProcessor } from '@backstage/plugin-catalog-node'; @@ -224,7 +224,7 @@ export type CatalogPermissionRule = PermissionRule; // @alpha -export const catalogPlugin: (option: unknown) => BackendRegistrable; +export const catalogPlugin: (options?: unknown) => BackendFeature; // @public (undocumented) export interface CatalogProcessingEngine { diff --git a/plugins/catalog-backend/migrations/20200511113813_init.js b/plugins/catalog-backend/migrations/20200511113813_init.js index b89ec57fe3..aa2ff6affa 100644 --- a/plugins/catalog-backend/migrations/20200511113813_init.js +++ b/plugins/catalog-backend/migrations/20200511113813_init.js @@ -92,7 +92,9 @@ exports.up = async function up(knex) { }) .alterTable('entities', table => { // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta - table.unique(['kind', 'name', 'namespace'], 'entities_unique_name'); + table.unique(['kind', 'name', 'namespace'], { + indexName: 'entities_unique_name', + }); }) // // entities_search diff --git a/plugins/catalog-backend/migrations/20200702153613_entities.js b/plugins/catalog-backend/migrations/20200702153613_entities.js index 6292063dac..86e0e48e40 100644 --- a/plugins/catalog-backend/migrations/20200702153613_entities.js +++ b/plugins/catalog-backend/migrations/20200702153613_entities.js @@ -89,7 +89,9 @@ exports.up = async function up(knex) { }) .alterTable('entities', table => { // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta - table.unique(['kind', 'name', 'namespace'], 'entities_unique_name'); + table.unique(['kind', 'name', 'namespace'], { + indexName: 'entities_unique_name', + }); }); await knex.schema.raw(`INSERT INTO entities SELECT * FROM tmp_entities`); @@ -199,7 +201,9 @@ exports.down = async function down(knex) { }) .alterTable('entities', table => { // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta - table.unique(['kind', 'name', 'namespace'], 'entities_unique_name'); + table.unique(['kind', 'name', 'namespace'], { + indexName: 'entities_unique_name', + }); }); await knex.schema.raw(`INSERT INTO entities SELECT * FROM tmp_entities`); diff --git a/plugins/catalog-backend/migrations/20201005122705_add_entity_full_name.js b/plugins/catalog-backend/migrations/20201005122705_add_entity_full_name.js index cd13f610cd..941b8a0a3f 100644 --- a/plugins/catalog-backend/migrations/20201005122705_add_entity_full_name.js +++ b/plugins/catalog-backend/migrations/20201005122705_add_entity_full_name.js @@ -39,7 +39,7 @@ exports.up = async function up(knex) { await knex.schema.alterTable('entities', table => { // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta - table.unique(['full_name'], 'entities_unique_full_name'); + table.unique(['full_name'], { indexName: 'entities_unique_full_name' }); table.dropUnique([], 'entities_unique_name'); }); }; @@ -51,7 +51,9 @@ exports.down = async function down(knex) { await knex.schema.alterTable('entities', table => { // https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta table.dropUnique([], 'entities_unique_full_name'); - table.unique(['kind', 'namespace', 'name'], 'entities_unique_name'); + table.unique(['kind', 'namespace', 'name'], { + indexName: 'entities_unique_name', + }); }); await knex.schema.alterTable('entities_search', table => { diff --git a/plugins/catalog-backend/migrations/20210302150147_refresh_state.js b/plugins/catalog-backend/migrations/20210302150147_refresh_state.js index db66b46305..da276940fa 100644 --- a/plugins/catalog-backend/migrations/20210302150147_refresh_state.js +++ b/plugins/catalog-backend/migrations/20210302150147_refresh_state.js @@ -65,7 +65,9 @@ exports.up = async function up(knex) { .dateTime('last_discovery_at') // TODO: timezone or change to epoch-millis or similar .notNullable() .comment('The last timestamp of which this entity was discovered'); - table.unique(['entity_ref'], 'refresh_state_entity_ref_uniq'); + table.unique(['entity_ref'], { + indexName: 'refresh_state_entity_ref_uniq', + }); table.index('entity_id', 'refresh_state_entity_id_idx'); table.index('entity_ref', 'refresh_state_entity_ref_idx'); table.index('next_update_at', 'refresh_state_next_update_at_idx'); diff --git a/plugins/catalog-backend/package.json b/plugins/catalog-backend/package.json index 92df8e87fc..e537678bde 100644 --- a/plugins/catalog-backend/package.json +++ b/plugins/catalog-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-backend", "description": "The Backstage backend plugin that provides the Backstage catalog", - "version": "1.3.0-next.3", + "version": "1.3.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,19 +34,19 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-plugin-api": "^0.1.0-next.0", - "@backstage/plugin-catalog-node": "^1.0.0-next.0", - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-plugin-api": "^0.1.1", + "@backstage/plugin-catalog-node": "^1.0.1", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-catalog-common": "^1.0.4-next.0", - "@backstage/plugin-permission-common": "^0.6.3-next.1", - "@backstage/plugin-permission-node": "^0.6.3-next.2", - "@backstage/plugin-scaffolder-common": "^1.1.2-next.0", - "@backstage/plugin-search-common": "^0.3.6-next.0", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-common": "^1.0.5", + "@backstage/plugin-permission-common": "^0.6.3", + "@backstage/plugin-permission-node": "^0.6.4", + "@backstage/plugin-scaffolder-common": "^1.1.2", + "@backstage/plugin-search-common": "^1.0.0", "@backstage/types": "^1.0.0", "@types/express": "^4.17.6", "codeowners-utils": "^1.0.2", @@ -70,17 +70,17 @@ "zod": "^3.11.6" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", - "@backstage/plugin-permission-common": "^0.6.3-next.1", - "@backstage/plugin-search-backend-node": "0.6.3-next.2", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", + "@backstage/plugin-permission-common": "^0.6.3", + "@backstage/plugin-search-backend-node": "1.0.1", "@types/core-js": "^2.5.4", "@types/git-url-parse": "^9.0.0", "@types/lodash": "^4.14.151", "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", "better-sqlite3": "^7.5.0", - "msw": "^0.44.0", + "msw": "^0.45.0", "supertest": "^6.1.3", "wait-for-expect": "^3.0.2", "luxon": "^3.0.0" diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts index 6a0986b345..9eaeb0e322 100644 --- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts +++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.test.ts @@ -429,6 +429,7 @@ describe('Default Processing Database', () => { if (step.expectConflict) { // eslint-disable-next-line jest/no-conditional-expect expect(mockLogger.warn).toHaveBeenCalledWith( + // eslint-disable-next-line jest/no-conditional-expect expect.stringMatching(/^Detected conflicting entityRef/), ); } else { diff --git a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts index c9b71d096d..1cf2643339 100644 --- a/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts +++ b/plugins/catalog-backend/src/database/DefaultProcessingDatabase.ts @@ -113,7 +113,10 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { // Delete old relations let previousRelationRows: DbRelationsRow[]; - if (tx.client.config.client.includes('sqlite3')) { + if ( + tx.client.config.client.includes('sqlite3') || + tx.client.config.client.includes('mysql') + ) { previousRelationRows = await tx('relations') .select('*') .where({ originating_entity_id: id }); @@ -201,6 +204,13 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { if (toRemove.length) { let removedCount = 0; + const rootId = () => { + if (tx.client.config.client.includes('mysql')) { + return tx.raw('CAST(NULL as UNSIGNED INT)', []); + } + + return tx.raw('CAST(NULL as INT)', []); + }; for (const refs of lodash.chunk(toRemove, 1000)) { /* WITH RECURSIVE @@ -266,7 +276,7 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { .withRecursive('ancestors', function ancestors(outer) { return outer .select({ - root_id: tx.raw('CAST(NULL as INT)', []), + root_id: rootId(), via_entity_ref: 'entity_ref', to_entity_ref: 'entity_ref', }) @@ -435,15 +445,26 @@ export class DefaultProcessingDatabase implements ProcessingDatabase { .orderBy('next_update_at', 'asc'); const interval = this.options.refreshInterval(); + + const nextUpdateAt = (refreshInterval: number) => { + if (tx.client.config.client.includes('sqlite3')) { + return tx.raw(`datetime('now', ?)`, [`${refreshInterval} seconds`]); + } + + if (tx.client.config.client.includes('mysql')) { + return tx.raw(`now() + interval ${refreshInterval} second`); + } + + return tx.raw(`now() + interval '${refreshInterval} seconds'`); + }; + await tx('refresh_state') .whereIn( 'entity_ref', items.map(i => i.entity_ref), ) .update({ - next_update_at: tx.client.config.client.includes('sqlite3') - ? tx.raw(`datetime('now', ?)`, [`${interval} seconds`]) - : tx.raw(`now() + interval '${interval} seconds'`), + next_update_at: nextUpdateAt(interval), }); return { diff --git a/plugins/catalog-backend/src/permissions/rules/createPropertyRule.test.ts b/plugins/catalog-backend/src/permissions/rules/createPropertyRule.test.ts index 80c86cf250..cb11add9ed 100644 --- a/plugins/catalog-backend/src/permissions/rules/createPropertyRule.test.ts +++ b/plugins/catalog-backend/src/permissions/rules/createPropertyRule.test.ts @@ -46,6 +46,22 @@ describe('createPropertyRule', () => { ).toBe(false); }); + it('returns false when specified key is an empty array', () => { + expect( + apply( + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test-component', + tags: [], + }, + }, + 'tags', + ), + ).toBe(false); + }); + it('returns true when specified key is present', () => { expect( apply( @@ -63,6 +79,22 @@ describe('createPropertyRule', () => { ), ).toBe(true); }); + + it('returns true when specified key is an array containing more than an element', () => { + expect( + apply( + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test-component', + tags: ['java'], + }, + }, + 'tags', + ), + ).toBe(true); + }); }); describe('key and value', () => { @@ -101,6 +133,23 @@ describe('createPropertyRule', () => { ).toBe(false); }); + it(`returns false when key is an array and doesn't contain the specified value`, () => { + expect( + apply( + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test-component', + tags: ['java'], + }, + }, + 'tags', + 'python', + ), + ).toBe(false); + }); + it('returns true when specified key and value is present', () => { expect( apply( @@ -119,6 +168,23 @@ describe('createPropertyRule', () => { ), ).toBe(true); }); + + it(`returns true when key is an array and contains the specified value`, () => { + expect( + apply( + { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'test-component', + tags: ['java', 'java11'], + }, + }, + 'tags', + 'java', + ), + ).toBe(true); + }); }); }); diff --git a/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts b/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts index 3808eced7b..57de5eb922 100644 --- a/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts +++ b/plugins/catalog-backend/src/permissions/rules/createPropertyRule.ts @@ -26,6 +26,13 @@ export const createPropertyRule = (propertyType: 'metadata' | 'spec') => resourceType: RESOURCE_TYPE_CATALOG_ENTITY, apply: (resource: Entity, key: string, value?: string) => { const foundValue = get(resource[propertyType], key); + + if (Array.isArray(foundValue)) { + if (value !== undefined) { + return foundValue.includes(value); + } + return foundValue.length > 0; + } if (value !== undefined) { return value === foundValue; } diff --git a/plugins/catalog-backend/src/service/CatalogBuilder.ts b/plugins/catalog-backend/src/service/CatalogBuilder.ts index a9ba5bbb23..e9e35301c3 100644 --- a/plugins/catalog-backend/src/service/CatalogBuilder.ts +++ b/plugins/catalog-backend/src/service/CatalogBuilder.ts @@ -91,7 +91,10 @@ import { } from '@backstage/plugin-permission-node'; import { AuthorizedEntitiesCatalog } from './AuthorizedEntitiesCatalog'; import { basicEntityFilter } from './request/basicEntityFilter'; -import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common'; +import { + catalogPermissions, + RESOURCE_TYPE_CATALOG_ENTITY, +} from '@backstage/plugin-catalog-common'; import { AuthorizedLocationService } from './AuthorizedLocationService'; /** @public */ @@ -435,6 +438,7 @@ export class CatalogBuilder { entitiesByRef[stringifyEntityRef(parseEntityRef(resourceRef))], ); }, + permissions: catalogPermissions, rules: this.permissionRules, }); const stitcher = new Stitcher(dbClient, logger); diff --git a/plugins/catalog-backend/src/service/CatalogPlugin.ts b/plugins/catalog-backend/src/service/CatalogPlugin.ts index b82797ec8b..64e1e52494 100644 --- a/plugins/catalog-backend/src/service/CatalogPlugin.ts +++ b/plugins/catalog-backend/src/service/CatalogPlugin.ts @@ -27,7 +27,7 @@ import { CatalogBuilder } from './CatalogBuilder'; import { CatalogProcessor, CatalogProcessingExtensionPoint, - catalogProcessingExtentionPoint, + catalogProcessingExtensionPoint, EntityProvider, } from '@backstage/plugin-catalog-node'; @@ -35,12 +35,16 @@ class CatalogExtensionPointImpl implements CatalogProcessingExtensionPoint { #processors = new Array(); #entityProviders = new Array(); - addProcessor(processor: CatalogProcessor): void { - this.#processors.push(processor); + addProcessor( + ...processors: Array> + ): void { + this.#processors.push(...processors.flat()); } - addEntityProvider(provider: EntityProvider): void { - this.#entityProviders.push(provider); + addEntityProvider( + ...providers: Array> + ): void { + this.#entityProviders.push(...providers.flat()); } get processors() { @@ -62,7 +66,7 @@ export const catalogPlugin = createBackendPlugin({ const processingExtensions = new CatalogExtensionPointImpl(); // plugins depending on this API will be initialized before this plugins init method is executed. env.registerExtensionPoint( - catalogProcessingExtentionPoint, + catalogProcessingExtensionPoint, processingExtensions, ); diff --git a/plugins/catalog-common/CHANGELOG.md b/plugins/catalog-common/CHANGELOG.md index 7fa70e5859..b3e150edc8 100644 --- a/plugins/catalog-common/CHANGELOG.md +++ b/plugins/catalog-common/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-catalog-common +## 1.0.5 + +### Patch Changes + +- 92103db537: Export aggregated list of all catalog permissions + +## 1.0.5-next.0 + +### Patch Changes + +- 92103db537: Export aggregated list of all catalog permissions + +## 1.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-search-common@1.0.0 + - @backstage/plugin-permission-common@0.6.3 + ## 1.0.4-next.0 ### Patch Changes diff --git a/plugins/catalog-common/api-report.md b/plugins/catalog-common/api-report.md index ab540d446b..b7eaf99d8b 100644 --- a/plugins/catalog-common/api-report.md +++ b/plugins/catalog-common/api-report.md @@ -49,6 +49,12 @@ export const catalogLocationDeletePermission: BasicPermission; // @alpha export const catalogLocationReadPermission: BasicPermission; +// @alpha +export const catalogPermissions: ( + | BasicPermission + | ResourcePermission<'catalog-entity'> +)[]; + // @alpha export const RESOURCE_TYPE_CATALOG_ENTITY = 'catalog-entity'; ``` diff --git a/plugins/catalog-common/package.json b/plugins/catalog-common/package.json index 82c0d72855..09911048ee 100644 --- a/plugins/catalog-common/package.json +++ b/plugins/catalog-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-common", "description": "Common functionalities for the catalog plugin", - "version": "1.0.4-next.0", + "version": "1.0.5", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,11 +34,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/plugin-permission-common": "^0.6.3-next.0", - "@backstage/plugin-search-common": "^0.3.6-next.0" + "@backstage/plugin-permission-common": "^0.6.3", + "@backstage/plugin-search-common": "^1.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.1" + "@backstage/cli": "^0.18.1" }, "files": [ "dist", diff --git a/plugins/catalog-common/src/index.ts b/plugins/catalog-common/src/index.ts index dfa90c448b..614948e56c 100644 --- a/plugins/catalog-common/src/index.ts +++ b/plugins/catalog-common/src/index.ts @@ -30,6 +30,7 @@ export { catalogLocationReadPermission, catalogLocationCreatePermission, catalogLocationDeletePermission, + catalogPermissions, } from './permissions'; export type { CatalogEntityPermission } from './permissions'; diff --git a/plugins/catalog-common/src/permissions.ts b/plugins/catalog-common/src/permissions.ts index aa95e8c00f..615f02a7fb 100644 --- a/plugins/catalog-common/src/permissions.ts +++ b/plugins/catalog-common/src/permissions.ts @@ -129,3 +129,17 @@ export const catalogLocationDeletePermission = createPermission({ action: 'delete', }, }); + +/** + * List of all catalog permissions. + * @alpha + */ +export const catalogPermissions = [ + catalogEntityReadPermission, + catalogEntityCreatePermission, + catalogEntityDeletePermission, + catalogEntityRefreshPermission, + catalogLocationReadPermission, + catalogLocationCreatePermission, + catalogLocationDeletePermission, +]; diff --git a/plugins/catalog-customized/.eslintrc.js b/plugins/catalog-customized/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/catalog-customized/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/catalog-customized/CHANGELOG.md b/plugins/catalog-customized/CHANGELOG.md new file mode 100644 index 0000000000..7d4ce71cb2 --- /dev/null +++ b/plugins/catalog-customized/CHANGELOG.md @@ -0,0 +1,17 @@ +# @internal/plugin-catalog-customized + +## 0.0.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.5.0 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog@1.5.0-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 diff --git a/plugins/catalog-customized/README.md b/plugins/catalog-customized/README.md new file mode 100644 index 0000000000..129d70ad58 --- /dev/null +++ b/plugins/catalog-customized/README.md @@ -0,0 +1,57 @@ +# Backstage Catalog Frontend + +This is the React frontend to customize Backstage [software +catalog](http://backstage.io/docs/features/software-catalog/software-catalog-overview). +This package supplies the example how it can be achieved. + +## Installation + +This `@internal/plugin-catalog-customized` package comes installed by default in example application of +Backstage application. + +To check if you already have the package, look under +`packages/app/package.json`, in the `dependencies` block, for +`@internal/plugin-catalog-customized`. The instructions below walk through restoring the +plugin, if you previously removed it. + +### Install the package + +```bash +# From your Backstage root directory +yarn add --cwd packages/app @internal/plugin-catalog-customized +``` + +### Add the plugin to your `packages/app` + +Add the import to a file where is your plugin catalog is defined: + +```diff +// packages/app/src/App.tsx + +import from '@internal/plugin-catalog-customized'; + +... + +import { + CatalogIndexPage, + CatalogEntityPage, +} from '@backstage/plugin-catalog'; + +... +``` + +## Development + +This frontend plugin can be started in a standalone mode from directly in this +package with `yarn start`. However, it will have limited functionality and that +process is most convenient when developing the catalog frontend plugin itself. + +To evaluate the catalog and have a greater amount of functionality available, +run the entire Backstage example application from the root folder: + +```bash +yarn dev +``` + +This will launch both frontend and backend in the same window, populated with +some example entities. diff --git a/plugins/catalog-customized/api-report.md b/plugins/catalog-customized/api-report.md new file mode 100644 index 0000000000..5cf6eefde1 --- /dev/null +++ b/plugins/catalog-customized/api-report.md @@ -0,0 +1,9 @@ +## API Report File for "@internal/plugin-catalog-customized" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +export * from '@backstage/plugin-catalog'; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/catalog-customized/package.json b/plugins/catalog-customized/package.json new file mode 100644 index 0000000000..747897da41 --- /dev/null +++ b/plugins/catalog-customized/package.json @@ -0,0 +1,49 @@ +{ + "name": "@internal/plugin-catalog-customized", + "description": "The internal Backstage Customizable plugin for browsing the Backstage catalog", + "version": "0.0.1", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": true, + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "frontend-plugin" + }, + "homepage": "https://backstage.io", + "repository": { + "type": "git", + "url": "https://github.com/backstage/backstage", + "directory": "plugins/catalog-customized" + }, + "keywords": [ + "backstage" + ], + "scripts": { + "build": "backstage-cli package build", + "start": "backstage-cli package start", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "diff": "backstage-cli plugin:diff", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack", + "clean": "backstage-cli package clean" + }, + "dependencies": { + "@backstage/plugin-catalog": "^1.5.0", + "@backstage/plugin-catalog-react": "^1.1.3" + }, + "devDependencies": { + "@types/react": "^16.13.1 || ^17.0.0" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/search/src/components/LegacySearchPage/Filters/index.ts b/plugins/catalog-customized/src/index.ts similarity index 82% rename from plugins/search/src/components/LegacySearchPage/Filters/index.ts rename to plugins/catalog-customized/src/index.ts index de890e0eaf..cc8aefeaa6 100644 --- a/plugins/search/src/components/LegacySearchPage/Filters/index.ts +++ b/plugins/catalog-customized/src/index.ts @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import './plugin'; -export { FiltersButton } from './FiltersButton'; -export { Filters } from './Filters'; -export type { FiltersState } from './Filters'; +export * from '@backstage/plugin-catalog'; diff --git a/plugins/catalog-customized/src/plugin.ts b/plugins/catalog-customized/src/plugin.ts new file mode 100644 index 0000000000..ce729d5226 --- /dev/null +++ b/plugins/catalog-customized/src/plugin.ts @@ -0,0 +1,22 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { catalogPlugin } from '@backstage/plugin-catalog'; + +// id: 'catalog-customized' +catalogPlugin.__experimentalReconfigure({ + createButtonTitle: 'New', +}); diff --git a/plugins/catalog-graph/CHANGELOG.md b/plugins/catalog-graph/CHANGELOG.md index 30e2b3dacb..398aec357f 100644 --- a/plugins/catalog-graph/CHANGELOG.md +++ b/plugins/catalog-graph/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-catalog-graph +## 0.2.20 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.2.20-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.2.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.2.19 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.2.19-next.3 ### Patch Changes diff --git a/plugins/catalog-graph/api-report.md b/plugins/catalog-graph/api-report.md index 1a2b03a292..ed4ca2a2c9 100644 --- a/plugins/catalog-graph/api-report.md +++ b/plugins/catalog-graph/api-report.md @@ -48,7 +48,8 @@ export const catalogGraphPlugin: BackstagePlugin< }, true >; - } + }, + {} >; // @public diff --git a/plugins/catalog-graph/package.json b/plugins/catalog-graph/package.json index 8de941e1a0..14f5aecb0d 100644 --- a/plugins/catalog-graph/package.json +++ b/plugins/catalog-graph/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-catalog-graph", - "version": "0.2.19-next.3", + "version": "0.2.20", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,12 +24,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -45,11 +45,11 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/plugin-catalog": "^1.4.0-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/plugin-catalog": "^1.5.0", + "@backstage/test-utils": "^1.1.3", "@backstage/types": "^1.0.0", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", diff --git a/plugins/catalog-graphql/CHANGELOG.md b/plugins/catalog-graphql/CHANGELOG.md index 7285215394..3f2ffd4f64 100644 --- a/plugins/catalog-graphql/CHANGELOG.md +++ b/plugins/catalog-graphql/CHANGELOG.md @@ -1,5 +1,20 @@ # @backstage/plugin-catalog-graphql +## 0.3.12 + +### Patch Changes + +- fa3eeee92d: Updated dependency `@graphql-tools/schema` to `^9.0.0`. + +## 0.3.11 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.0 + ## 0.3.11-next.1 ### Patch Changes diff --git a/plugins/catalog-graphql/package.json b/plugins/catalog-graphql/package.json index 651d54b811..533d07ac1e 100644 --- a/plugins/catalog-graphql/package.json +++ b/plugins/catalog-graphql/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-graphql", "description": "An experimental Backstage catalog GraphQL module", - "version": "0.3.11-next.1", + "version": "0.3.12", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,7 +34,7 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", "@backstage/types": "^1.0.0", "apollo-server": "^3.0.0", @@ -46,14 +46,14 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/test-utils": "^1.1.3", "@graphql-codegen/cli": "^2.3.1", "@graphql-codegen/graphql-modules-preset": "^2.3.2", "@graphql-codegen/typescript": "^2.4.2", "@graphql-codegen/typescript-resolvers": "^2.4.3", - "@graphql-tools/schema": "^8.3.1", - "msw": "^0.44.0" + "@graphql-tools/schema": "^9.0.0", + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/catalog-import/CHANGELOG.md b/plugins/catalog-import/CHANGELOG.md index d057b5c1df..bbed459737 100644 --- a/plugins/catalog-import/CHANGELOG.md +++ b/plugins/catalog-import/CHANGELOG.md @@ -1,5 +1,64 @@ # @backstage/plugin-catalog-import +## 0.8.11 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/integration-react@1.1.3 + +## 0.8.11-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + +## 0.8.11-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.8.10 + +### Patch Changes + +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 272106fdad: Support use without `integrations` or only integrations without frontend visible properties (e.g., `bitbucketCloud`) being configured by checking `integrations.github` directly without attempting to load `integrations`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/errors@1.1.0 + ## 0.8.10-next.3 ### Patch Changes diff --git a/plugins/catalog-import/api-report.md b/plugins/catalog-import/api-report.md index 5a9e8f03fd..90c01255b0 100644 --- a/plugins/catalog-import/api-report.md +++ b/plugins/catalog-import/api-report.md @@ -133,6 +133,7 @@ const catalogImportPlugin: BackstagePlugin< { importPage: RouteRef; }, + {}, {} >; export { catalogImportPlugin }; diff --git a/plugins/catalog-import/package.json b/plugins/catalog-import/package.json index 65a3c89bd5..63120c05b0 100644 --- a/plugins/catalog-import/package.json +++ b/plugins/catalog-import/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-import", "description": "A Backstage plugin the helps you import entities into your catalog", - "version": "0.8.10-next.3", + "version": "0.8.11", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,15 +34,15 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/integration-react": "^1.1.2-next.3", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/integration-react": "^1.1.3", + "@backstage/plugin-catalog-react": "^1.1.3", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -60,17 +60,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/catalog-node/CHANGELOG.md b/plugins/catalog-node/CHANGELOG.md index a70deb4769..04b65bb4ba 100644 --- a/plugins/catalog-node/CHANGELOG.md +++ b/plugins/catalog-node/CHANGELOG.md @@ -1,5 +1,38 @@ # @backstage/plugin-catalog-node +## 1.0.1 + +### Patch Changes + +- 0599732ec0: Refactored experimental backend system with new type names. +- 56e1b4b89c: Fixed typos in alpha types. +- Updated dependencies + - @backstage/backend-plugin-api@0.1.1 + +## 1.0.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.1-next.0 + +## 1.0.0 + +### Major Changes + +- 9a6aba1d85: This package houses stable types from the `@backstage/plugin-catalog-backend` package and is intended for creation of catalog modules. Prefer importing from this package over the `@backstage/plugin-catalog-backend` package. + +### Minor Changes + +- 91c1d12123: Added alpha exports for the new experimental backend system. + +### Patch Changes + +- Updated dependencies + - @backstage/backend-plugin-api@0.1.0 + - @backstage/catalog-model@1.1.0 + - @backstage/errors@1.1.0 + ## 1.0.0-next.0 ### Major Changes diff --git a/plugins/catalog-node/api-report.md b/plugins/catalog-node/api-report.md index 0449708bc3..26617910b9 100644 --- a/plugins/catalog-node/api-report.md +++ b/plugins/catalog-node/api-report.md @@ -7,19 +7,23 @@ import { CompoundEntityRef } from '@backstage/catalog-model'; import { Entity } from '@backstage/catalog-model'; +import { ExtensionPoint } from '@backstage/backend-plugin-api'; import { JsonValue } from '@backstage/types'; -import { ServiceRef } from '@backstage/backend-plugin-api'; // @alpha (undocumented) export interface CatalogProcessingExtensionPoint { // (undocumented) - addEntityProvider(provider: EntityProvider): void; + addEntityProvider( + ...providers: Array> + ): void; // (undocumented) - addProcessor(processor: CatalogProcessor): void; + addProcessor( + ...processors: Array> + ): void; } // @alpha (undocumented) -export const catalogProcessingExtentionPoint: ServiceRef; +export const catalogProcessingExtensionPoint: ExtensionPoint; // @public (undocumented) export type CatalogProcessor = { diff --git a/plugins/catalog-node/package.json b/plugins/catalog-node/package.json index 8671ccbc9a..08f61b699c 100644 --- a/plugins/catalog-node/package.json +++ b/plugins/catalog-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-node", "description": "The plugin-catalog-node module for @backstage/plugin-catalog-backend", - "version": "1.0.0-next.0", + "version": "1.0.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -25,14 +25,14 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-plugin-api": "^0.1.0-next.0", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/errors": "1.1.0-next.0", + "@backstage/backend-plugin-api": "^0.1.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/errors": "1.1.0", "@backstage/types": "^1.0.0" }, "devDependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/cli": "^0.18.0-next.3" + "@backstage/backend-common": "^0.15.0", + "@backstage/cli": "^0.18.1" }, "files": [ "dist", diff --git a/plugins/catalog-node/src/extensions.ts b/plugins/catalog-node/src/extensions.ts index 560d9d4db1..8dd9d8579a 100644 --- a/plugins/catalog-node/src/extensions.ts +++ b/plugins/catalog-node/src/extensions.ts @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { createServiceRef } from '@backstage/backend-plugin-api'; +import { createExtensionPoint } from '@backstage/backend-plugin-api'; import { EntityProvider } from './api'; import { CatalogProcessor } from './api/processor'; @@ -21,14 +21,18 @@ import { CatalogProcessor } from './api/processor'; * @alpha */ export interface CatalogProcessingExtensionPoint { - addProcessor(processor: CatalogProcessor): void; - addEntityProvider(provider: EntityProvider): void; + addProcessor( + ...processors: Array> + ): void; + addEntityProvider( + ...providers: Array> + ): void; } /** * @alpha */ -export const catalogProcessingExtentionPoint = - createServiceRef({ +export const catalogProcessingExtensionPoint = + createExtensionPoint({ id: 'catalog.processing', }); diff --git a/plugins/catalog-node/src/index.ts b/plugins/catalog-node/src/index.ts index fc7a1b1b67..02ae325a9a 100644 --- a/plugins/catalog-node/src/index.ts +++ b/plugins/catalog-node/src/index.ts @@ -21,6 +21,6 @@ */ export type { CatalogProcessingExtensionPoint } from './extensions'; -export { catalogProcessingExtentionPoint } from './extensions'; +export { catalogProcessingExtensionPoint } from './extensions'; export * from './api'; export * from './processing'; diff --git a/plugins/catalog-react/CHANGELOG.md b/plugins/catalog-react/CHANGELOG.md index 5acff71be3..964e1e0017 100644 --- a/plugins/catalog-react/CHANGELOG.md +++ b/plugins/catalog-react/CHANGELOG.md @@ -1,5 +1,100 @@ # @backstage/plugin-catalog-react +## 1.1.3 + +### Patch Changes + +- 44e691a7f9: Modify description column to not use auto width. +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-common@1.0.5 + - @backstage/plugin-permission-react@0.4.4 + +## 1.1.3-next.2 + +### Patch Changes + +- 44e691a7f9: Modify description column to not use auto width. +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 1.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/integration@1.3.0-next.1 + +## 1.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-permission-react@0.4.4-next.0 + +## 1.1.2 + +### Patch Changes + +- 72622d9143: Updated dependency `yaml` to `^2.0.0`. +- be26d95141: Added new `EntityProcessingStatusPicker` that will filter for entities with orphans and/or errors. + + If you are using the default Catalog page this picker will be added automatically. For those who have customized their Catalog page you'll need to add this manually by doing something like this: + + ```diff + ... + import { + CatalogFilterLayout, + EntityTypePicker, + UserListPicker, + EntityTagPicker + + EntityProcessingStatusPicker, + } from '@backstage/plugin-catalog-react'; + ... + export const CustomCatalogPage = ({ + columns, + actions, + initiallySelectedFilter = 'owned', + }: CatalogPageProps) => { + return ( + ... + + + + + + ... + }; + ``` + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + - @backstage/plugin-catalog-common@1.0.4 + - @backstage/plugin-permission-react@0.4.3 + ## 1.1.2-next.3 ### Patch Changes diff --git a/plugins/catalog-react/api-report.md b/plugins/catalog-react/api-report.md index 5232c49150..6e0ba235b7 100644 --- a/plugins/catalog-react/api-report.md +++ b/plugins/catalog-react/api-report.md @@ -109,20 +109,13 @@ export const columnFactories: Readonly<{ createEntityRefColumn(options: { defaultKind?: string; }): TableColumn; - createEntityRelationColumn({ - title, - relation, - defaultKind, - filter: entityFilter, - }: { + createEntityRelationColumn(options: { title: string; relation: string; - defaultKind?: string | undefined; - filter?: - | { - kind: string; - } - | undefined; + defaultKind?: string; + filter?: { + kind: string; + }; }): TableColumn; createOwnerColumn(): TableColumn; createDomainColumn(): TableColumn; @@ -324,12 +317,7 @@ export const EntityTable: { createEntityRefColumn(options: { defaultKind?: string | undefined; }): TableColumn; - createEntityRelationColumn({ - title, - relation, - defaultKind, - filter: entityFilter, - }: { + createEntityRelationColumn(options: { title: string; relation: string; defaultKind?: string | undefined; diff --git a/plugins/catalog-react/package.json b/plugins/catalog-react/package.json index 8fb16bbbaa..08987df622 100644 --- a/plugins/catalog-react/package.json +++ b/plugins/catalog-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog-react", "description": "A frontend library that helps other Backstage plugins interact with the catalog", - "version": "1.1.2-next.3", + "version": "1.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,16 +34,16 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-catalog-common": "^1.0.4-next.0", - "@backstage/plugin-permission-common": "^0.6.3-next.1", - "@backstage/plugin-permission-react": "^0.4.3-next.1", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-common": "^1.0.5", + "@backstage/plugin-permission-common": "^0.6.3", + "@backstage/plugin-permission-react": "^0.4.4", + "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@backstage/version-bridge": "^1.0.1", "@material-ui/core": "^4.12.2", @@ -63,11 +63,11 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/plugin-catalog-common": "^1.0.4-next.0", - "@backstage/plugin-scaffolder-common": "^1.1.2-next.0", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/plugin-catalog-common": "^1.0.5", + "@backstage/plugin-scaffolder-common": "^1.1.2", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", diff --git a/plugins/catalog-react/src/components/EntityTable/columns.tsx b/plugins/catalog-react/src/components/EntityTable/columns.tsx index 08eb31bea3..292235c78c 100644 --- a/plugins/catalog-react/src/components/EntityTable/columns.tsx +++ b/plugins/catalog-react/src/components/EntityTable/columns.tsx @@ -70,17 +70,14 @@ export const columnFactories = Object.freeze({ ), }; }, - createEntityRelationColumn({ - title, - relation, - defaultKind, - filter: entityFilter, - }: { + createEntityRelationColumn(options: { title: string; relation: string; defaultKind?: string; filter?: { kind: string }; }): TableColumn { + const { title, relation, defaultKind, filter: entityFilter } = options; + function getRelations(entity: T): CompoundEntityRef[] { return getEntityRelations(entity, relation, entityFilter); } @@ -147,7 +144,6 @@ export const columnFactories = Object.freeze({ line={2} /> ), - width: 'auto', }; }, createSpecLifecycleColumn(): TableColumn { diff --git a/plugins/catalog/CHANGELOG.md b/plugins/catalog/CHANGELOG.md index 9c10c67b5f..578b51c61b 100644 --- a/plugins/catalog/CHANGELOG.md +++ b/plugins/catalog/CHANGELOG.md @@ -1,5 +1,169 @@ # @backstage/plugin-catalog +## 1.5.0 + +### Minor Changes + +- 80da5162c7: Plugin catalog has been modified to use an experimental feature where you can customize the title of the create button. + + You can modify it by doing: + + ```typescript jsx + import { catalogPlugin } from '@backstage/plugin-catalog'; + + catalogPlugin.__experimentalReconfigure({ + createButtonTitle: 'New', + }); + ``` + +- fe94398418: Allow changing the subtitle of the `CatalogTable` component + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-catalog-common@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## 1.5.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-search-react@1.0.1-next.1 + +## 1.5.0-next.1 + +### Minor Changes + +- fe94398418: Allow changing the subtitle of the `CatalogTable` component + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## 1.5.0-next.0 + +### Minor Changes + +- 80da5162c7: Plugin catalog has been modified to use an experimental feature where you can customize the title of the create button. + + You can modify it by doing: + + ```typescript jsx + import { catalogPlugin } from '@backstage/plugin-catalog'; + + catalogPlugin.__experimentalReconfigure({ + createButtonTitle: 'New', + }); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + +## 1.4.0 + +### Minor Changes + +- 97c46f2359: Add `spec.targets` (or `spec.target`) for Location entities at the `CatalogTable`. +- cf288221d1: Add `Location` target(s) to `AboutCard`. +- a274fe38b9: Add hidden title column to catalog and API table to enable filtering by title. + +### Patch Changes + +- dcaf1cb418: Previously, the color of the Entity Context Menu (in the Entity Page Header) was hardcoded as `white`. + + This was an issue for themes that use a header with a white background. By default, the color of the icon is now `theme.page.fontColor`. + + It can now also be overridden in the theme, which is only necessary if the header title, subtitle and three-dots icon need to have different colors. For example: + + ```typescript + export function createThemeOverrides(theme: BackstageTheme): Overrides { + return { + PluginCatalogEntityContextMenu: { + button: { + color: 'blue', + }, + }, + ... + }, + ... + } + ``` + +- f1dcc6f3c6: Use entity type predicates from catalog-model +- 258057a4b9: Adding ability to customize the "unregister entity" menu item in the entity context menu on the entity page with options 'visible','hidden','disabled'.With this three new options, one can hide the "unregister entity" menu item from the list, disable or keep it enabled. + + The boolean input for "unregister entity" will be deprecated later in favour of the above three options. + +- 385389d23c: Updated to remove usage of the `bursts` object in the theme palette +- be26d95141: Added new `EntityProcessingStatusPicker` that will filter for entities with orphans and/or errors. + + If you are using the default Catalog page this picker will be added automatically. For those who have customized their Catalog page you'll need to add this manually by doing something like this: + + ```diff + ... + import { + CatalogFilterLayout, + EntityTypePicker, + UserListPicker, + EntityTagPicker + + EntityProcessingStatusPicker, + } from '@backstage/plugin-catalog-react'; + ... + export const CustomCatalogPage = ({ + columns, + actions, + initiallySelectedFilter = 'owned', + }: CatalogPageProps) => { + return ( + ... + + + + + + ... + }; + ``` + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/catalog-client@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + - @backstage/plugin-catalog-common@1.0.4 + ## 1.4.0-next.3 ### Patch Changes diff --git a/plugins/catalog/api-report.md b/plugins/catalog/api-report.md index bfdf62bdb0..98bc7ab89e 100644 --- a/plugins/catalog/api-report.md +++ b/plugins/catalog/api-report.md @@ -79,6 +79,8 @@ export interface CatalogKindHeaderProps { initialFilter?: string; } +// Warning: (ae-forgotten-export) The symbol "CatalogInputPluginOptions" needs to be exported by the entry point index.d.ts +// // @public (undocumented) export const catalogPlugin: BackstagePlugin< { @@ -99,7 +101,8 @@ export const catalogPlugin: BackstagePlugin< }, true >; - } + }, + CatalogInputPluginOptions >; // @public (undocumented) @@ -132,6 +135,7 @@ export const CatalogTable: { ): TableColumn; createSystemColumn(): TableColumn; createOwnerColumn(): TableColumn; + createSpecTargetsColumn(): TableColumn; createSpecTypeColumn(): TableColumn; createSpecLifecycleColumn(): TableColumn; createMetadataDescriptionColumn(): TableColumn; @@ -153,6 +157,8 @@ export interface CatalogTableProps { // (undocumented) columns?: TableColumn[]; // (undocumented) + subtitle?: string; + // (undocumented) tableOptions?: TableProps['options']; } diff --git a/plugins/catalog/package.json b/plugins/catalog/package.json index 66718424cd..ba20f0d285 100644 --- a/plugins/catalog/package.json +++ b/plugins/catalog/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-catalog", "description": "The Backstage plugin for browsing the Backstage catalog", - "version": "1.4.0-next.3", + "version": "1.5.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,17 +34,17 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration-react": "^1.1.2-next.3", - "@backstage/plugin-catalog-common": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/plugin-search-common": "^0.3.6-next.0", - "@backstage/plugin-search-react": "^0.2.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/integration-react": "^1.1.3", + "@backstage/plugin-catalog-common": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/plugin-search-common": "^1.0.0", + "@backstage/plugin-search-react": "^1.0.1", + "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -61,11 +61,11 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/plugin-permission-react": "^0.4.3-next.1", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/plugin-permission-react": "^0.4.4", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", diff --git a/plugins/catalog/src/components/AboutCard/AboutContent.test.tsx b/plugins/catalog/src/components/AboutCard/AboutContent.test.tsx index 87ee8cc6ec..f4dbb73b45 100644 --- a/plugins/catalog/src/components/AboutCard/AboutContent.test.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutContent.test.tsx @@ -411,6 +411,7 @@ describe('', () => { }, spec: { type: 'root', + target: 'https://backstage.io', }, relations: [], }; @@ -440,6 +441,10 @@ describe('', () => { expect(queryByText('Lifecycle')).not.toBeInTheDocument(); expect(getByText('Tags')).toBeInTheDocument(); expect(getByText('Tags').nextSibling).toHaveTextContent('tag-1'); + expect(getByText('Targets')).toBeInTheDocument(); + expect(getByText('Targets').nextSibling).toHaveTextContent( + 'https://backstage.io', + ); }); it('highlights missing required fields', async () => { diff --git a/plugins/catalog/src/components/AboutCard/AboutContent.tsx b/plugins/catalog/src/components/AboutCard/AboutContent.tsx index ee1dad5d39..260a0eccbf 100644 --- a/plugins/catalog/src/components/AboutCard/AboutContent.tsx +++ b/plugins/catalog/src/components/AboutCard/AboutContent.tsx @@ -16,6 +16,7 @@ import { Entity, + getEntitySourceLocation, RELATION_OWNED_BY, RELATION_PART_OF, } from '@backstage/catalog-model'; @@ -23,9 +24,11 @@ import { EntityRefLinks, getEntityRelations, } from '@backstage/plugin-catalog-react'; +import { JsonArray } from '@backstage/types'; import { Chip, Grid, makeStyles, Typography } from '@material-ui/core'; import React from 'react'; import { AboutField } from './AboutField'; +import { LinksGridList } from '../EntityLinksCard/LinksGridList'; const useStyles = makeStyles({ description: { @@ -42,6 +45,30 @@ export interface AboutContentProps { entity: Entity; } +function getLocationTargetHref( + target: string, + type: string, + entitySourceLocation: { + type: string; + target: string; + }, +): string { + if (type === 'url' || target.includes('://')) { + return target; + } + + const srcLocationUrl = + entitySourceLocation.type === 'file' + ? `file://${entitySourceLocation.target}` + : entitySourceLocation.target; + + if (type === 'file' || entitySourceLocation.type === 'file') { + return new URL(target, srcLocationUrl).href; + } + + return srcLocationUrl; +} + /** @public */ export function AboutContent(props: AboutContentProps) { const { entity } = props; @@ -69,6 +96,18 @@ export function AboutContent(props: AboutContentProps) { }); const ownedByRelations = getEntityRelations(entity, RELATION_OWNED_BY); + let entitySourceLocation: + | { + type: string; + target: string; + } + | undefined; + try { + entitySourceLocation = getEntitySourceLocation(entity); + } catch (e) { + entitySourceLocation = undefined; + } + return ( @@ -159,6 +198,23 @@ export function AboutContent(props: AboutContentProps) { ))} + {isLocation && (entity?.spec?.targets || entity?.spec?.target) && ( + + target as string) + .map(target => ({ + text: target, + href: getLocationTargetHref( + target, + (entity?.spec?.type || 'unknown') as string, + entitySourceLocation!, + ), + }))} + /> + + )} ); } diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx index c3135e5697..cc00a57314 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.test.tsx @@ -23,8 +23,10 @@ import { } from '@backstage/catalog-model'; import { TableColumn, TableProps } from '@backstage/core-components'; import { + createPlugin, IdentityApi, identityApiRef, + PluginProvider, ProfileInfo, storageApiRef, } from '@backstage/core-plugin-api'; @@ -133,6 +135,22 @@ describe('DefaultCatalogPage', () => { }; const storageApi = MockStorageApi.create(); + type TestInputPluginOptions = { + 'key-1': string; + }; + + type TestPluginOptions = { + 'key-1': string; + 'key-2': string; + }; + + const plugin = createPlugin({ + id: 'my-plugin', + __experimentalConfigure(_: TestInputPluginOptions): TestPluginOptions { + return { 'key-1': 'value-1', 'key-2': 'value-2' }; + }, + }); + const renderWrapped = (children: React.ReactNode) => renderWithEffects( wrapInTestApp( @@ -144,7 +162,7 @@ describe('DefaultCatalogPage', () => { [starredEntitiesApiRef, new MockStarredEntitiesApi()], ]} > - {children} + {children} , { mountedRoutes: { diff --git a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx index 51ef12ac74..39c19d717a 100644 --- a/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx +++ b/plugins/catalog/src/components/CatalogPage/DefaultCatalogPage.tsx @@ -39,6 +39,7 @@ import React from 'react'; import { createComponentRouteRef } from '../../routes'; import { CatalogTable, CatalogTableRow } from '../CatalogTable'; import { CatalogKindHeader } from '../CatalogKindHeader'; +import { useCatalogPluginOptions } from '../../options'; /** * Props for root catalog pages. @@ -65,6 +66,8 @@ export function DefaultCatalogPage(props: DefaultCatalogPageProps) { useApi(configApiRef).getOptionalString('organization.name') ?? 'Backstage'; const createComponentLink = useRouteRef(createComponentRouteRef); + const { createButtonTitle } = useCatalogPluginOptions(); + return ( @@ -73,7 +76,7 @@ export function DefaultCatalogPage(props: DefaultCatalogPageProps) { titleComponent={} > All your software catalog entities diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx index 0d2b80e3c1..bd78cecaf0 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.test.tsx @@ -21,12 +21,12 @@ import { } from '@backstage/catalog-model'; import { ApiProvider } from '@backstage/core-app-api'; import { + EntityKindFilter, entityRouteRef, MockEntityListContextProvider, + MockStarredEntitiesApi, starredEntitiesApiRef, UserListFilter, - EntityKindFilter, - MockStarredEntitiesApi, } from '@backstage/plugin-catalog-react'; import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; import { act, fireEvent } from '@testing-library/react'; @@ -215,7 +215,14 @@ describe('CatalogTable component', () => { }, { kind: 'location', - expectedColumns: ['Name', 'Type', 'Description', 'Tags', 'Actions'], + expectedColumns: [ + 'Name', + 'Type', + 'Targets', + 'Description', + 'Tags', + 'Actions', + ], }, { kind: 'resource', @@ -299,4 +306,29 @@ describe('CatalogTable component', () => { }, 20_000, ); + it('should render the subtitle when it is specified', async () => { + const entity = { + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', + metadata: { + name: 'component1', + annotations: { [ANNOTATION_EDIT_URL]: 'https://other.place' }, + }, + }; + + const { getByText } = await renderInTestApp( + + + + + , + { + mountedRoutes: { + '/catalog/:namespace/:kind/:name': entityRouteRef, + }, + }, + ); + + expect(getByText('Should be rendered')).toBeInTheDocument(); + }); }); diff --git a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx index 96937c52c2..6bc18d7a90 100644 --- a/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx +++ b/plugins/catalog/src/components/CatalogTable/CatalogTable.tsx @@ -19,18 +19,6 @@ import { RELATION_OWNED_BY, RELATION_PART_OF, } from '@backstage/catalog-model'; -import { - humanizeEntityRef, - getEntityRelations, - useEntityList, - useStarredEntities, -} from '@backstage/plugin-catalog-react'; -import Edit from '@material-ui/icons/Edit'; -import OpenInNew from '@material-ui/icons/OpenInNew'; -import { capitalize } from 'lodash'; -import React, { useMemo } from 'react'; -import { columnFactories } from './columns'; -import { CatalogTableRow } from './types'; import { CodeSnippet, Table, @@ -38,10 +26,22 @@ import { TableProps, WarningPanel, } from '@backstage/core-components'; -import StarBorder from '@material-ui/icons/StarBorder'; -import { withStyles } from '@material-ui/core/styles'; -import Star from '@material-ui/icons/Star'; +import { + getEntityRelations, + humanizeEntityRef, + useEntityList, + useStarredEntities, +} from '@backstage/plugin-catalog-react'; import { Typography } from '@material-ui/core'; +import { withStyles } from '@material-ui/core/styles'; +import Edit from '@material-ui/icons/Edit'; +import OpenInNew from '@material-ui/icons/OpenInNew'; +import Star from '@material-ui/icons/Star'; +import StarBorder from '@material-ui/icons/StarBorder'; +import { capitalize } from 'lodash'; +import React, { useMemo } from 'react'; +import { columnFactories } from './columns'; +import { CatalogTableRow } from './types'; /** * Props for {@link CatalogTable}. @@ -52,6 +52,7 @@ export interface CatalogTableProps { columns?: TableColumn[]; actions?: TableProps['actions']; tableOptions?: TableProps['options']; + subtitle?: string; } const YellowStar = withStyles({ @@ -62,7 +63,7 @@ const YellowStar = withStyles({ /** @public */ export const CatalogTable = (props: CatalogTableProps) => { - const { columns, actions, tableOptions } = props; + const { columns, actions, tableOptions, subtitle } = props; const { isStarredEntity, toggleStarredEntity } = useStarredEntities(); const { loading, error, entities, filters } = useEntityList(); @@ -83,9 +84,13 @@ export const CatalogTable = (props: CatalogTableProps) => { case 'system': return [columnFactories.createOwnerColumn()]; case 'group': - case 'location': case 'template': return [columnFactories.createSpecTypeColumn()]; + case 'location': + return [ + columnFactories.createSpecTypeColumn(), + columnFactories.createSpecTargetsColumn(), + ]; default: return [ columnFactories.createSystemColumn(), @@ -222,6 +227,7 @@ export const CatalogTable = (props: CatalogTableProps) => { title={`${titlePreamble} (${entities.length})`} data={rows} actions={actions || defaultActions} + subtitle={subtitle} /> ); }; diff --git a/plugins/catalog/src/components/CatalogTable/columns.tsx b/plugins/catalog/src/components/CatalogTable/columns.tsx index d8b52e276e..19d160c0e2 100644 --- a/plugins/catalog/src/components/CatalogTable/columns.tsx +++ b/plugins/catalog/src/components/CatalogTable/columns.tsx @@ -23,6 +23,7 @@ import { Chip } from '@material-ui/core'; import { CatalogTableRow } from './types'; import { OverflowTooltip, TableColumn } from '@backstage/core-components'; import { Entity } from '@backstage/catalog-model'; +import { JsonArray } from '@backstage/types'; // The columnFactories symbol is not directly exported, but through the // CatalogTable.columns field. @@ -82,11 +83,30 @@ export const columnFactories = Object.freeze({ ), }; }, + createSpecTargetsColumn(): TableColumn { + return { + title: 'Targets', + field: 'entity.spec.targets', + render: ({ entity }) => ( + <> + {(entity?.spec?.targets || entity?.spec?.target) && ( + + )} + + ), + }; + }, createSpecTypeColumn(): TableColumn { return { title: 'Type', field: 'entity.spec.type', hidden: true, + width: 'auto', }; }, createSpecLifecycleColumn(): TableColumn { @@ -129,6 +149,7 @@ export const columnFactories = Object.freeze({ ))} ), + width: 'auto', }; }, createTitleColumn(options?: { diff --git a/plugins/catalog/src/options.ts b/plugins/catalog/src/options.ts new file mode 100644 index 0000000000..1d8b972ec2 --- /dev/null +++ b/plugins/catalog/src/options.ts @@ -0,0 +1,28 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { usePluginOptions } from '@backstage/core-plugin-api'; + +export type CatalogPluginOptions = { + createButtonTitle: string; +}; + +export type CatalogInputPluginOptions = { + createButtonTitle: string; +}; + +export const useCatalogPluginOptions = () => + usePluginOptions(); diff --git a/plugins/catalog/src/plugin.ts b/plugins/catalog/src/plugin.ts index 1b9083e7ca..5419854cb6 100644 --- a/plugins/catalog/src/plugin.ts +++ b/plugins/catalog/src/plugin.ts @@ -43,6 +43,7 @@ import { HasSubcomponentsCardProps } from './components/HasSubcomponentsCard'; import { HasSystemsCardProps } from './components/HasSystemsCard'; import { RelatedEntitiesCardProps } from './components/RelatedEntitiesCard'; import { rootRouteRef } from './routes'; +import { CatalogInputPluginOptions, CatalogPluginOptions } from './options'; /** @public */ export const catalogPlugin = createPlugin({ @@ -72,6 +73,14 @@ export const catalogPlugin = createPlugin({ createComponent: createComponentRouteRef, viewTechDoc: viewTechDocRouteRef, }, + __experimentalConfigure( + options?: CatalogInputPluginOptions, + ): CatalogPluginOptions { + const defaultOptions = { + createButtonTitle: 'Create', + }; + return { ...defaultOptions, ...options }; + }, }); /** @public */ diff --git a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md index 2f863ebd11..163776416b 100644 --- a/plugins/cicd-statistics-module-gitlab/CHANGELOG.md +++ b/plugins/cicd-statistics-module-gitlab/CHANGELOG.md @@ -1,5 +1,31 @@ # @backstage/plugin-cicd-statistics-module-gitlab +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-cicd-statistics@0.1.10 + +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-cicd-statistics@0.1.10-next.0 + +## 0.1.3 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-cicd-statistics@0.1.9 + ## 0.1.3-next.1 ### Patch Changes diff --git a/plugins/cicd-statistics-module-gitlab/package.json b/plugins/cicd-statistics-module-gitlab/package.json index 12ed1fb773..b034b48177 100644 --- a/plugins/cicd-statistics-module-gitlab/package.json +++ b/plugins/cicd-statistics-module-gitlab/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics-module-gitlab", "description": "CI/CD Statistics plugin module; Gitlab CICD", - "version": "0.1.3-next.1", + "version": "0.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,16 +29,16 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/plugin-cicd-statistics": "^0.1.9-next.1", + "@backstage/plugin-cicd-statistics": "^0.1.10", "@gitbeaker/browser": "^35.6.0", "@gitbeaker/core": "^35.6.0", "luxon": "^3.0.0", "p-limit": "^4.0.0", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/catalog-model": "^1.1.0-next.3" + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/catalog-model": "^1.1.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3" + "@backstage/cli": "^0.18.1" }, "files": [ "dist" diff --git a/plugins/cicd-statistics/CHANGELOG.md b/plugins/cicd-statistics/CHANGELOG.md index afc0811c29..268e32b825 100644 --- a/plugins/cicd-statistics/CHANGELOG.md +++ b/plugins/cicd-statistics/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-cicd-statistics +## 0.1.10 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.1.10-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + +## 0.1.9 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + ## 0.1.9-next.1 ### Patch Changes diff --git a/plugins/cicd-statistics/api-report.md b/plugins/cicd-statistics/api-report.md index 3c7a52cdad..e49c6b27dc 100644 --- a/plugins/cicd-statistics/api-report.md +++ b/plugins/cicd-statistics/api-report.md @@ -107,6 +107,7 @@ export const cicdStatisticsPlugin: BackstagePlugin< { entityContent: RouteRef; }, + {}, {} >; diff --git a/plugins/cicd-statistics/package.json b/plugins/cicd-statistics/package.json index 3b90b365dc..10e5e5ea38 100644 --- a/plugins/cicd-statistics/package.json +++ b/plugins/cicd-statistics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cicd-statistics", "description": "A frontend plugin visualizing CI/CD pipeline statistics (build time)", - "version": "0.1.9-next.1", + "version": "0.1.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,12 +34,12 @@ }, "devDependencies": { "@types/react": "^16.13.1 || ^17.0.0", - "@types/luxon": "^2.0.5" + "@types/luxon": "^3.0.0" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", "@date-io/luxon": "^1.3.13", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.11.2", diff --git a/plugins/circleci/CHANGELOG.md b/plugins/circleci/CHANGELOG.md index ac26a01e0d..b76be5b5b2 100644 --- a/plugins/circleci/CHANGELOG.md +++ b/plugins/circleci/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-circleci +## 0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.3.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.3.7-next.3 ### Patch Changes diff --git a/plugins/circleci/api-report.md b/plugins/circleci/api-report.md index 5cdf916514..034cfae3ee 100644 --- a/plugins/circleci/api-report.md +++ b/plugins/circleci/api-report.md @@ -44,10 +44,7 @@ export class CircleCIApi { ): Promise; // (undocumented) getBuilds( - { - limit, - offset, - }: { + pagination: { limit: number; offset: number; }, @@ -75,7 +72,7 @@ export const circleCIBuildRouteRef: SubRouteRef>; // Warning: (ae-missing-release-tag) "circleCIPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -const circleCIPlugin: BackstagePlugin<{}, {}>; +const circleCIPlugin: BackstagePlugin<{}, {}, {}>; export { circleCIPlugin }; export { circleCIPlugin as plugin }; diff --git a/plugins/circleci/package.json b/plugins/circleci/package.json index 2c376c26c7..c1ab1d2141 100644 --- a/plugins/circleci/package.json +++ b/plugins/circleci/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-circleci", "description": "A Backstage plugin that integrates towards Circle CI", - "version": "0.3.7-next.3", + "version": "0.3.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,11 +35,11 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -55,10 +55,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", @@ -66,7 +66,7 @@ "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/circleci/src/api/CircleCIApi.ts b/plugins/circleci/src/api/CircleCIApi.ts index 78b8b378d6..931feec4d5 100644 --- a/plugins/circleci/src/api/CircleCIApi.ts +++ b/plugins/circleci/src/api/CircleCIApi.ts @@ -62,9 +62,10 @@ export class CircleCIApi { } async getBuilds( - { limit = 10, offset = 0 }: { limit: number; offset: number }, + pagination: { limit: number; offset: number }, options: Partial, ) { + const { limit = 10, offset = 0 } = pagination; return getBuildSummaries('', { options: { limit, diff --git a/plugins/cloudbuild/CHANGELOG.md b/plugins/cloudbuild/CHANGELOG.md index f7a5b7b35a..18ebdec1df 100644 --- a/plugins/cloudbuild/CHANGELOG.md +++ b/plugins/cloudbuild/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-cloudbuild +## 0.3.8 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.3.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.3.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.3.7-next.3 ### Patch Changes diff --git a/plugins/cloudbuild/api-report.md b/plugins/cloudbuild/api-report.md index 4077a8991a..34b50b54d8 100644 --- a/plugins/cloudbuild/api-report.md +++ b/plugins/cloudbuild/api-report.md @@ -60,31 +60,20 @@ export interface BUILD { // @public (undocumented) export const CLOUDBUILD_ANNOTATION = 'google.com/cloudbuild-project-slug'; -// Warning: (ae-missing-release-tag) "CloudbuildApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type CloudbuildApi = { - listWorkflowRuns: (request: { + listWorkflowRuns: (options: { projectId: string; }) => Promise; - getWorkflow: ({ - projectId, - id, - }: { + getWorkflow: (options: { projectId: string; id: string; }) => Promise; - getWorkflowRun: ({ - projectId, - id, - }: { + getWorkflowRun: (options: { projectId: string; id: string; }) => Promise; - reRunWorkflow: ({ - projectId, - runId, - }: { + reRunWorkflow: (options: { projectId: string; runId: string; }) => Promise; @@ -95,43 +84,27 @@ export type CloudbuildApi = { // @public (undocumented) export const cloudbuildApiRef: ApiRef; -// Warning: (ae-missing-release-tag) "CloudbuildClient" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class CloudbuildClient implements CloudbuildApi { constructor(googleAuthApi: OAuthApi); // (undocumented) getToken(): Promise; // (undocumented) - getWorkflow({ - projectId, - id, - }: { + getWorkflow(options: { projectId: string; id: string; }): Promise; // (undocumented) - getWorkflowRun({ - projectId, - id, - }: { + getWorkflowRun(options: { projectId: string; id: string; }): Promise; // (undocumented) - listWorkflowRuns({ - projectId, - }: { + listWorkflowRuns(options: { projectId: string; }): Promise; // (undocumented) - reRunWorkflow({ - projectId, - runId, - }: { - projectId: string; - runId: string; - }): Promise; + reRunWorkflow(options: { projectId: string; runId: string }): Promise; } // Warning: (ae-missing-release-tag) "cloudbuildPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -141,6 +114,7 @@ const cloudbuildPlugin: BackstagePlugin< { entityContent: RouteRef; }, + {}, {} >; export { cloudbuildPlugin }; @@ -154,18 +128,14 @@ export const EntityCloudbuildContent: () => JSX.Element; // Warning: (ae-missing-release-tag) "EntityLatestCloudbuildRunCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const EntityLatestCloudbuildRunCard: ({ - branch, -}: { +export const EntityLatestCloudbuildRunCard: (props: { branch: string; }) => JSX.Element; // Warning: (ae-missing-release-tag) "EntityLatestCloudbuildsForBranchCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const EntityLatestCloudbuildsForBranchCard: ({ - branch, -}: { +export const EntityLatestCloudbuildsForBranchCard: (props: { branch: string; }) => JSX.Element; @@ -189,18 +159,12 @@ export { isCloudbuildAvailable as isPluginApplicableToEntity }; // Warning: (ae-missing-release-tag) "LatestWorkflowRunCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const LatestWorkflowRunCard: ({ - branch, -}: { - branch: string; -}) => JSX.Element; +export const LatestWorkflowRunCard: (props: { branch: string }) => JSX.Element; // Warning: (ae-missing-release-tag) "LatestWorkflowsForBranchCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const LatestWorkflowsForBranchCard: ({ - branch, -}: { +export const LatestWorkflowsForBranchCard: (props: { branch: string; }) => JSX.Element; diff --git a/plugins/cloudbuild/package.json b/plugins/cloudbuild/package.json index fcac623363..f55b942543 100644 --- a/plugins/cloudbuild/package.json +++ b/plugins/cloudbuild/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cloudbuild", "description": "A Backstage plugin that integrates towards Google Cloud Build", - "version": "0.3.7-next.3", + "version": "0.3.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,11 +34,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -52,17 +52,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/cloudbuild/src/api/CloudbuildApi.ts b/plugins/cloudbuild/src/api/CloudbuildApi.ts index 92ea8511fe..eeaf269cde 100644 --- a/plugins/cloudbuild/src/api/CloudbuildApi.ts +++ b/plugins/cloudbuild/src/api/CloudbuildApi.ts @@ -24,28 +24,20 @@ export const cloudbuildApiRef = createApiRef({ id: 'plugin.cloudbuild.service', }); +/** @public */ export type CloudbuildApi = { - listWorkflowRuns: (request: { + listWorkflowRuns: (options: { projectId: string; }) => Promise; - getWorkflow: ({ - projectId, - id, - }: { + getWorkflow: (options: { projectId: string; id: string; }) => Promise; - getWorkflowRun: ({ - projectId, - id, - }: { + getWorkflowRun: (options: { projectId: string; id: string; }) => Promise; - reRunWorkflow: ({ - projectId, - runId, - }: { + reRunWorkflow: (options: { projectId: string; runId: string; }) => Promise; diff --git a/plugins/cloudbuild/src/api/CloudbuildClient.ts b/plugins/cloudbuild/src/api/CloudbuildClient.ts index cbd47e84e9..035b20f63d 100644 --- a/plugins/cloudbuild/src/api/CloudbuildClient.ts +++ b/plugins/cloudbuild/src/api/CloudbuildClient.ts @@ -21,20 +21,18 @@ import { } from '../api/types'; import { OAuthApi } from '@backstage/core-plugin-api'; +/** @public */ export class CloudbuildClient implements CloudbuildApi { constructor(private readonly googleAuthApi: OAuthApi) {} - async reRunWorkflow({ - projectId, - runId, - }: { + async reRunWorkflow(options: { projectId: string; runId: string; }): Promise { await fetch( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( - projectId, - )}/builds/${encodeURIComponent(runId)}:retry`, + options.projectId, + )}/builds/${encodeURIComponent(options.runId)}:retry`, { headers: new Headers({ Accept: '*/*', @@ -43,14 +41,13 @@ export class CloudbuildClient implements CloudbuildApi { }, ); } - async listWorkflowRuns({ - projectId, - }: { + + async listWorkflowRuns(options: { projectId: string; }): Promise { const workflowRuns = await fetch( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( - projectId, + options.projectId, )}/builds`, { headers: new Headers({ @@ -65,17 +62,15 @@ export class CloudbuildClient implements CloudbuildApi { return builds; } - async getWorkflow({ - projectId, - id, - }: { + + async getWorkflow(options: { projectId: string; id: string; }): Promise { const workflow = await fetch( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( - projectId, - )}/builds/${encodeURIComponent(id)}`, + options.projectId, + )}/builds/${encodeURIComponent(options.id)}`, { headers: new Headers({ Accept: '*/*', @@ -88,17 +83,15 @@ export class CloudbuildClient implements CloudbuildApi { return build; } - async getWorkflowRun({ - projectId, - id, - }: { + + async getWorkflowRun(options: { projectId: string; id: string; }): Promise { const workflow = await fetch( `https://cloudbuild.googleapis.com/v1/projects/${encodeURIComponent( - projectId, - )}/builds/${encodeURIComponent(id)}`, + options.projectId, + )}/builds/${encodeURIComponent(options.id)}`, { headers: new Headers({ Accept: '*/*', diff --git a/plugins/cloudbuild/src/components/Cards/Cards.tsx b/plugins/cloudbuild/src/components/Cards/Cards.tsx index 82e0eb1b88..75c9ee432b 100644 --- a/plugins/cloudbuild/src/components/Cards/Cards.tsx +++ b/plugins/cloudbuild/src/components/Cards/Cards.tsx @@ -72,11 +72,8 @@ const WidgetContent = ({ ); }; -export const LatestWorkflowRunCard = ({ - branch = 'master', -}: { - branch: string; -}) => { +export const LatestWorkflowRunCard = (props: { branch: string }) => { + const { branch = 'master' } = props; const { entity } = useEntity(); const errorApi = useApi(errorApiRef); const projectId = entity?.metadata.annotations?.[CLOUDBUILD_ANNOTATION] || ''; @@ -103,11 +100,8 @@ export const LatestWorkflowRunCard = ({ ); }; -export const LatestWorkflowsForBranchCard = ({ - branch = 'master', -}: { - branch: string; -}) => { +export const LatestWorkflowsForBranchCard = (props: { branch: string }) => { + const { branch = 'master' } = props; const { entity } = useEntity(); return ( diff --git a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx index a6a63770ca..0e532178e1 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunDetails/WorkflowRunDetails.tsx @@ -61,8 +61,8 @@ const useStyles = makeStyles(theme => ({ }, })); -export const WorkflowRunDetails = ({ entity }: { entity: Entity }) => { - const { value: projectName, loading, error } = useProjectName(entity); +export const WorkflowRunDetails = (props: { entity: Entity }) => { + const { value: projectName, loading, error } = useProjectName(props.entity); const [projectId] = (projectName ?? '/').split('/'); const details = useWorkflowRunsDetails(projectId); diff --git a/plugins/cloudbuild/src/components/WorkflowRunStatus/WorkflowRunStatus.tsx b/plugins/cloudbuild/src/components/WorkflowRunStatus/WorkflowRunStatus.tsx index 3f43d84ce4..fce8566dc0 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunStatus/WorkflowRunStatus.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunStatus/WorkflowRunStatus.tsx @@ -23,11 +23,8 @@ import { StatusError, } from '@backstage/core-components'; -export const WorkflowRunStatus = ({ - status, -}: { - status: string | undefined; -}) => { +export const WorkflowRunStatus = (props: { status: string | undefined }) => { + const { status } = props; if (status === undefined) return null; switch (status.toLocaleLowerCase('en-US')) { case 'queued': diff --git a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx index d79d481cd4..a8e2a12ea8 100644 --- a/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx +++ b/plugins/cloudbuild/src/components/WorkflowRunsTable/WorkflowRunsTable.tsx @@ -164,8 +164,8 @@ export const WorkflowRunsTableView = ({ ); }; -export const WorkflowRunsTable = ({ entity }: { entity: Entity }) => { - const { value: projectName, loading } = useProjectName(entity); +export const WorkflowRunsTable = (props: { entity: Entity }) => { + const { value: projectName, loading } = useProjectName(props.entity); const [projectId] = (projectName ?? '/').split('/'); const [tableProps, { retry, setPage, setPageSize }] = useWorkflowRuns({ diff --git a/plugins/cloudbuild/src/components/useWorkflowRuns.ts b/plugins/cloudbuild/src/components/useWorkflowRuns.ts index f2e107ea3f..424f08e38d 100644 --- a/plugins/cloudbuild/src/components/useWorkflowRuns.ts +++ b/plugins/cloudbuild/src/components/useWorkflowRuns.ts @@ -33,7 +33,8 @@ export type WorkflowRun = { rerun: () => void; }; -export function useWorkflowRuns({ projectId }: { projectId: string }) { +export function useWorkflowRuns(options: { projectId: string }) { + const { projectId } = options; const api = useApi(cloudbuildApiRef); const errorApi = useApi(errorApiRef); diff --git a/plugins/code-climate/CHANGELOG.md b/plugins/code-climate/CHANGELOG.md index d3824d7ff5..6202bf67a3 100644 --- a/plugins/code-climate/CHANGELOG.md +++ b/plugins/code-climate/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/plugin-code-climate +## 0.1.8 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- 831a8fee86: Send Authorization headers in fetch requests using FetchApi in Code Climate plugin to fix unauthorized requests to Backstage backends with authentication enabled. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.1.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.1.8-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.1.7-next.3 ### Patch Changes diff --git a/plugins/code-climate/api-report.md b/plugins/code-climate/api-report.md index 11366384d3..5ef53cf543 100644 --- a/plugins/code-climate/api-report.md +++ b/plugins/code-climate/api-report.md @@ -8,6 +8,7 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { FetchApi } from '@backstage/core-plugin-api'; import { RouteRef } from '@backstage/core-plugin-api'; // Warning: (ae-missing-release-tag) "CodeClimateApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -48,6 +49,7 @@ export const codeClimatePlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; @@ -73,7 +75,8 @@ export const mockData: CodeClimateData; // // @public (undocumented) export class ProductionCodeClimateApi implements CodeClimateApi { - constructor(discoveryApi: DiscoveryApi); + // Warning: (ae-forgotten-export) The symbol "Options" needs to be exported by the entry point index.d.ts + constructor(options: Options); // (undocumented) fetchAllData(options: { apiUrl: string; diff --git a/plugins/code-climate/package.json b/plugins/code-climate/package.json index 3fe1ff5ae1..70b990943e 100644 --- a/plugins/code-climate/package.json +++ b/plugins/code-climate/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-code-climate", - "version": "0.1.7-next.3", + "version": "0.1.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,11 +23,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -40,18 +40,18 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/humanize-duration": "^3.27.1", "@types/jest": "^26.0.7", - "@types/luxon": "^2.0.9", + "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/code-climate/src/api/production-api.ts b/plugins/code-climate/src/api/production-api.ts index 665d7e9f63..81ba6b9ad6 100644 --- a/plugins/code-climate/src/api/production-api.ts +++ b/plugins/code-climate/src/api/production-api.ts @@ -22,7 +22,7 @@ import { CodeClimateIssuesData, } from './code-climate-data'; import { CodeClimateApi } from './code-climate-api'; -import { DiscoveryApi } from '@backstage/core-plugin-api'; +import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'; import { Duration } from 'luxon'; import humanizeDuration from 'humanize-duration'; @@ -34,8 +34,19 @@ const codeSmellsQuery = `${basicIssuesOptions}&${categoriesFilter}=Complexity`; const duplicationQuery = `${basicIssuesOptions}&${categoriesFilter}=Duplication`; const otherIssuesQuery = `${basicIssuesOptions}&${categoriesFilter}=Bug%20Risk`; +type Options = { + discoveryApi: DiscoveryApi; + fetchApi: FetchApi; +}; + export class ProductionCodeClimateApi implements CodeClimateApi { - constructor(private readonly discoveryApi: DiscoveryApi) {} + private readonly discoveryApi: DiscoveryApi; + private readonly fetchApi: FetchApi; + + constructor(options: Options) { + this.discoveryApi = options.discoveryApi; + this.fetchApi = options.fetchApi; + } async fetchAllData(options: { apiUrl: string; @@ -44,7 +55,6 @@ export class ProductionCodeClimateApi implements CodeClimateApi { testReportID: string; }): Promise { const { apiUrl, repoID, snapshotID, testReportID } = options; - const [ maintainabilityResponse, testCoverageResponse, @@ -52,15 +62,19 @@ export class ProductionCodeClimateApi implements CodeClimateApi { duplicationResponse, otherIssuesResponse, ] = await Promise.all([ - await fetch(`${apiUrl}/repos/${repoID}/snapshots/${snapshotID}`), - await fetch(`${apiUrl}/repos/${repoID}/test_reports/${testReportID}`), - await fetch( + await this.fetchApi.fetch( + `${apiUrl}/repos/${repoID}/snapshots/${snapshotID}`, + ), + await this.fetchApi.fetch( + `${apiUrl}/repos/${repoID}/test_reports/${testReportID}`, + ), + await this.fetchApi.fetch( `${apiUrl}/repos/${repoID}/snapshots/${snapshotID}/issues?${codeSmellsQuery}`, ), - await fetch( + await this.fetchApi.fetch( `${apiUrl}/repos/${repoID}/snapshots/${snapshotID}/issues?${duplicationQuery}`, ), - await fetch( + await this.fetchApi.fetch( `${apiUrl}/repos/${repoID}/snapshots/${snapshotID}/issues?${otherIssuesQuery}`, ), ]); @@ -109,7 +123,7 @@ export class ProductionCodeClimateApi implements CodeClimateApi { 'proxy', )}/codeclimate/api`; - const repoResponse = await fetch(`${apiUrl}/repos/${repoID}`); + const repoResponse = await this.fetchApi.fetch(`${apiUrl}/repos/${repoID}`); if (!repoResponse.ok) { throw new Error('Failed fetching Code Climate info'); diff --git a/plugins/code-climate/src/plugin.ts b/plugins/code-climate/src/plugin.ts index dcf86f1e19..54502b6355 100644 --- a/plugins/code-climate/src/plugin.ts +++ b/plugins/code-climate/src/plugin.ts @@ -20,7 +20,7 @@ import { createPlugin, createRouteRef, discoveryApiRef, - identityApiRef, + fetchApiRef, createComponentExtension, } from '@backstage/core-plugin-api'; @@ -37,9 +37,10 @@ export const codeClimatePlugin = createPlugin({ api: codeClimateApiRef, deps: { discoveryApi: discoveryApiRef, - identityApi: identityApiRef, + fetchApi: fetchApiRef, }, - factory: ({ discoveryApi }) => new ProductionCodeClimateApi(discoveryApi), + factory: ({ discoveryApi, fetchApi }) => + new ProductionCodeClimateApi({ discoveryApi, fetchApi }), }), ], routes: { diff --git a/plugins/code-coverage-backend/CHANGELOG.md b/plugins/code-coverage-backend/CHANGELOG.md index 95a7188dd4..0d07616343 100644 --- a/plugins/code-coverage-backend/CHANGELOG.md +++ b/plugins/code-coverage-backend/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-code-coverage-backend +## 0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + +## 0.2.0 + +### Minor Changes + +- d70aaa7622: Cleaned up API exports. + + The `CodeCoverageApi` and `makeRouter` exports have been removed from the backend, since they were not meant to be exported in the first place. + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/errors@1.1.0 + ## 0.2.0-next.3 ### Minor Changes diff --git a/plugins/code-coverage-backend/package.json b/plugins/code-coverage-backend/package.json index 5fe9242e54..0d03994a92 100644 --- a/plugins/code-coverage-backend/package.json +++ b/plugins/code-coverage-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage-backend", "description": "A Backstage backend plugin that helps you keep track of your code coverage", - "version": "0.2.0-next.3", + "version": "0.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,12 +23,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -39,10 +39,10 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/express-xml-bodyparser": "^0.3.2", "@types/supertest": "^2.0.8", - "msw": "^0.44.0", + "msw": "^0.45.0", "supertest": "^6.1.6", "xml2js": "^0.4.23" }, diff --git a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts index 635debca02..ed913e2c79 100644 --- a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts +++ b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.test.ts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +import { Knex as KnexType } from 'knex'; import { DatabaseManager } from '@backstage/backend-common'; import { stringifyEntityRef } from '@backstage/catalog-model'; import { ConfigReader } from '@backstage/config'; @@ -95,12 +96,24 @@ const coverage: Array = [ ], }, ]; - +function createDatabaseManager( + client: KnexType, + skipMigrations: boolean = false, +) { + return { + getClient: async () => client, + migrations: { + skip: skipMigrations, + }, + }; +} let database: CodeCoverageStore; describe('CodeCoverageDatabase', () => { beforeAll(async () => { const client = await db.getClient(); - database = await CodeCoverageDatabase.create(client); + const databaseManager = createDatabaseManager(client); + database = await CodeCoverageDatabase.create(databaseManager); + await database.insertCodeCoverage(coverage[0]); await database.insertCodeCoverage(coverage[1]); }); diff --git a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts index 9235f3a8fd..4cbcd76fe0 100644 --- a/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts +++ b/plugins/code-coverage-backend/src/service/CodeCoverageDatabase.ts @@ -13,7 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { resolvePackagePath } from '@backstage/backend-common'; +import { + PluginDatabaseManager, + resolvePackagePath, +} from '@backstage/backend-common'; import { NotFoundError } from '@backstage/errors'; import { parseEntityRef, stringifyEntityRef } from '@backstage/catalog-model'; import { Knex } from 'knex'; @@ -41,10 +44,17 @@ const migrationsDir = resolvePackagePath( ); export class CodeCoverageDatabase implements CodeCoverageStore { - static async create(knex: Knex): Promise { - await knex.migrate.latest({ - directory: migrationsDir, - }); + static async create( + database: PluginDatabaseManager, + ): Promise { + const knex = await database.getClient(); + + if (!database.migrations?.skip) { + await knex.migrate.latest({ + directory: migrationsDir, + }); + } + return new CodeCoverageDatabase(knex); } diff --git a/plugins/code-coverage-backend/src/service/router.ts b/plugins/code-coverage-backend/src/service/router.ts index 37279b549f..b87b21bffd 100644 --- a/plugins/code-coverage-backend/src/service/router.ts +++ b/plugins/code-coverage-backend/src/service/router.ts @@ -57,9 +57,7 @@ export const makeRouter = async ( ): Promise => { const { config, logger, discovery, database, urlReader } = options; - const codeCoverageDatabase = await CodeCoverageDatabase.create( - await database.getClient(), - ); + const codeCoverageDatabase = await CodeCoverageDatabase.create(database); const codecovUrl = await discovery.getExternalBaseUrl('code-coverage'); const catalogApi: CatalogApi = new CatalogClient({ discoveryApi: discovery }); const scm = ScmIntegrations.fromConfig(config); diff --git a/plugins/code-coverage/CHANGELOG.md b/plugins/code-coverage/CHANGELOG.md index 6c7c034d39..9e4282b28a 100644 --- a/plugins/code-coverage/CHANGELOG.md +++ b/plugins/code-coverage/CHANGELOG.md @@ -1,5 +1,54 @@ # @backstage/plugin-code-coverage +## 0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.2.0 + +### Minor Changes + +- d70aaa7622: Cleaned up API exports. + + The `Router` export has been removed; users are expected to use `EntityCodeCoverageContent` instead. + + The `isPluginApplicableToEntity` helper has been deprecated, in favor of the `isCodeCoverageAvailable` helper. + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.2.0-next.3 ### Minor Changes diff --git a/plugins/code-coverage/api-report.md b/plugins/code-coverage/api-report.md index 152cc93103..5dcb5fcfd1 100644 --- a/plugins/code-coverage/api-report.md +++ b/plugins/code-coverage/api-report.md @@ -14,6 +14,7 @@ export const codeCoveragePlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; diff --git a/plugins/code-coverage/package.json b/plugins/code-coverage/package.json index bd90d2abee..2b7d10ec0b 100644 --- a/plugins/code-coverage/package.json +++ b/plugins/code-coverage/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-code-coverage", "description": "A Backstage plugin that helps you keep track of your code coverage", - "version": "0.2.0-next.3", + "version": "0.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,13 +24,13 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -46,10 +46,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", @@ -58,7 +58,7 @@ "@types/node": "^16.11.26", "@types/recharts": "^1.8.15", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/codescene/CHANGELOG.md b/plugins/codescene/CHANGELOG.md index c184656efb..f753f291f7 100644 --- a/plugins/codescene/CHANGELOG.md +++ b/plugins/codescene/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-codescene +## 0.1.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.1.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.1.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 15201b1032: Updated dependency `rc-progress` to `3.4.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.1.2-next.3 ### Patch Changes diff --git a/plugins/codescene/api-report.md b/plugins/codescene/api-report.md index 962a20a618..75dfddd09e 100644 --- a/plugins/codescene/api-report.md +++ b/plugins/codescene/api-report.md @@ -23,6 +23,7 @@ export const codescenePlugin: BackstagePlugin< projectId: string; }>; }, + {}, {} >; diff --git a/plugins/codescene/package.json b/plugins/codescene/package.json index 516280149f..2f6a6f0c92 100644 --- a/plugins/codescene/package.json +++ b/plugins/codescene/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-codescene", - "version": "0.1.2-next.3", + "version": "0.1.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,10 +23,10 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.9.10", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.57", @@ -38,16 +38,16 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "*", "@types/node": "*", - "msw": "^0.44.0", + "msw": "^0.45.0", "cross-fetch": "^3.1.5" }, "files": [ diff --git a/plugins/config-schema/CHANGELOG.md b/plugins/config-schema/CHANGELOG.md index 50d5d5934c..f69905cce2 100644 --- a/plugins/config-schema/CHANGELOG.md +++ b/plugins/config-schema/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-config-schema +## 0.1.31 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.1.31-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.1.31-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.30 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.1.30-next.3 ### Patch Changes diff --git a/plugins/config-schema/api-report.md b/plugins/config-schema/api-report.md index f3b620738f..4b9f47c950 100644 --- a/plugins/config-schema/api-report.md +++ b/plugins/config-schema/api-report.md @@ -38,6 +38,7 @@ export const configSchemaPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; diff --git a/plugins/config-schema/package.json b/plugins/config-schema/package.json index 3e70dfbf63..e1fb598c7f 100644 --- a/plugins/config-schema/package.json +++ b/plugins/config-schema/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-config-schema", "description": "A Backstage plugin that lets you browse the configuration schema of your app", - "version": "0.1.30-next.3", + "version": "0.1.31", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -25,10 +25,10 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -41,17 +41,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/cost-insights-common/CHANGELOG.md b/plugins/cost-insights-common/CHANGELOG.md index 0a55b342fc..52d167c17c 100644 --- a/plugins/cost-insights-common/CHANGELOG.md +++ b/plugins/cost-insights-common/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-cost-insights-common +## 0.1.1 + +### Patch Changes + +- daf4b33e34: Add name property to Group + +## 0.1.1-next.0 + +### Patch Changes + +- daf4b33e34: Add name property to Group + +## 0.1.0 + +### Minor Changes + +- 81dd5ea989: Introduces a new isomorphic @backstage/plugin-cost-insight-common package to contain shared types across all other cost insights packages and modules. + ## 0.1.0-next.0 ### Minor Changes diff --git a/plugins/cost-insights-common/api-report.md b/plugins/cost-insights-common/api-report.md index a5f7045854..8d9e2d030d 100644 --- a/plugins/cost-insights-common/api-report.md +++ b/plugins/cost-insights-common/api-report.md @@ -44,6 +44,7 @@ export interface Entity { // @public (undocumented) export type Group = { id: string; + name?: string; }; // @public (undocumented) diff --git a/plugins/cost-insights-common/package.json b/plugins/cost-insights-common/package.json index 2918462e09..03d3b11ea8 100644 --- a/plugins/cost-insights-common/package.json +++ b/plugins/cost-insights-common/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cost-insights-common", "description": "Common functionalities for the cost-insights plugin", - "version": "0.1.0-next.0", + "version": "0.1.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,7 +34,7 @@ }, "dependencies": {}, "devDependencies": { - "@backstage/cli": "^0.18.0-next.2" + "@backstage/cli": "^0.18.1" }, "files": [ "dist" diff --git a/plugins/cost-insights-common/src/types/Group.ts b/plugins/cost-insights-common/src/types/Group.ts index b34cac083f..ad384abe7b 100644 --- a/plugins/cost-insights-common/src/types/Group.ts +++ b/plugins/cost-insights-common/src/types/Group.ts @@ -19,4 +19,5 @@ */ export type Group = { id: string; + name?: string; }; diff --git a/plugins/cost-insights/CHANGELOG.md b/plugins/cost-insights/CHANGELOG.md index 05d8d5d640..080f2e1f41 100644 --- a/plugins/cost-insights/CHANGELOG.md +++ b/plugins/cost-insights/CHANGELOG.md @@ -1,5 +1,52 @@ # @backstage/plugin-cost-insights +## 0.11.30 + +### Patch Changes + +- b746eca638: Make `products` field optional in the config +- daf4b33e34: Add name property to Group +- 08562ebe11: Display minus sign in trends in `CostOverviewCard` +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-cost-insights-common@0.1.1 + +## 0.11.30-next.1 + +### Patch Changes + +- b746eca638: Make `products` field optional in the config +- daf4b33e34: Add name property to Group +- Updated dependencies + - @backstage/plugin-cost-insights-common@0.1.1-next.0 + - @backstage/core-components@0.11.0-next.2 + +## 0.11.30-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.11.29 + +### Patch Changes + +- 3e032a5de2: Move cost-insights data specific API types (non react) into an @backstage/plugin-cost-insights-common + isomorphic package. This allows these types to be shared in any backend packages or other cost-insight + modules. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-cost-insights-common@0.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + ## 0.11.29-next.3 ### Patch Changes diff --git a/plugins/cost-insights/README.md b/plugins/cost-insights/README.md index 824cf6f9fe..2b20da2f26 100644 --- a/plugins/cost-insights/README.md +++ b/plugins/cost-insights/README.md @@ -120,14 +120,24 @@ To expose the plugin to your users, you can integrate the `cost-insights` route ## Configuration -Cost Insights has only two required configuration fields: a map of cloud `products` for showing cost breakdowns and `engineerCost` - the average yearly cost of an engineer including benefits. Products must be defined as keys on the `products` field. +Cost Insights has only one required configuration field: `engineerCost` - the average yearly cost of an engineer including benefits. + +### Basic + +```yaml +## ./app-config.yaml +costInsights: + engineerCost: 200000 +``` + +### Products (Optional) + +For showing cost breakdowns you can define a map of cloud products. They must be defined as keys on the `products` field. A user-friendly name is **required**. You can optionally supply a product `icon` to display in Cost Insights navigation. See the [type file](https://github.com/backstage/backstage/blob/master/plugins/cost-insights/src/types/Icon.ts) for supported types and Material UI icon [mappings](https://github.com/backstage/backstage/blob/master/plugins/cost-insights/src/utils/navigation.tsx). **Note:** Product keys should be unique and camelCased. Backstage does not support underscores in configuration keys. -### Basic - ```yaml ## ./app-config.yaml costInsights: diff --git a/plugins/cost-insights/api-report.md b/plugins/cost-insights/api-report.md index 5a9024de5a..2a4cecc4eb 100644 --- a/plugins/cost-insights/api-report.md +++ b/plugins/cost-insights/api-report.md @@ -320,7 +320,12 @@ export const CostGrowthIndicator: ({ // @public (undocumented) export type CostGrowthIndicatorProps = TypographyProps & { change: ChangeStatistic; - formatter?: (change: ChangeStatistic) => Maybe; + formatter?: ( + change: ChangeStatistic, + options?: { + absolute: boolean; + }, + ) => Maybe; }; // Warning: (ae-missing-release-tag) "CostGrowthProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -382,6 +387,7 @@ const costInsightsPlugin: BackstagePlugin< growthAlerts: RouteRef; unlabeledDataflowAlerts: RouteRef; }, + {}, {} >; export { costInsightsPlugin }; diff --git a/plugins/cost-insights/config.d.ts b/plugins/cost-insights/config.d.ts index 8438ca6561..4144b6d6a5 100644 --- a/plugins/cost-insights/config.d.ts +++ b/plugins/cost-insights/config.d.ts @@ -21,7 +21,7 @@ export interface Config { */ engineerCost: number; - products: { + products?: { [kind: string]: { /** * @visibility frontend diff --git a/plugins/cost-insights/package.json b/plugins/cost-insights/package.json index 9dfa45e67c..52d33c83d9 100644 --- a/plugins/cost-insights/package.json +++ b/plugins/cost-insights/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-cost-insights", "description": "A Backstage plugin that helps you keep track of your cloud spend", - "version": "0.11.29-next.3", + "version": "0.11.30", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,12 +34,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-cost-insights-common": "^0.1.0-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-cost-insights-common": "^0.1.1", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -61,10 +61,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", @@ -76,7 +76,7 @@ "@types/yup": "^0.29.13", "canvas": "^2.6.1", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx b/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx index 592f57d389..e7746495d6 100644 --- a/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx +++ b/plugins/cost-insights/src/components/CostGrowth/CostGrowthIndicator.tsx @@ -25,7 +25,10 @@ import { useCostGrowthStyles as useStyles } from '../../utils/styles'; export type CostGrowthIndicatorProps = TypographyProps & { change: ChangeStatistic; - formatter?: (change: ChangeStatistic) => Maybe; + formatter?: ( + change: ChangeStatistic, + options?: { absolute: boolean }, + ) => Maybe; }; export const CostGrowthIndicator = ({ @@ -44,7 +47,7 @@ export const CostGrowthIndicator = ({ return ( - {formatter ? formatter(change) : change.ratio} + {formatter ? formatter(change, { absolute: true }) : change.ratio} {growth === GrowthType.Excess && } {growth === GrowthType.Savings && } diff --git a/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx b/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx index cccf8b60cd..015a6279da 100644 --- a/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx +++ b/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.test.tsx @@ -35,7 +35,7 @@ describe('', () => { const rendered = await renderInTestApp( ', () => { const rendered = await renderInTestApp( ', () => { const rendered = await renderInTestApp( ', () => { const rendered = await renderInTestApp( ', () => { ); expect(rendered.queryByText(/this is awkward/)).toBeInTheDocument(); }); + + describe.each` + hasCostData | alerts + ${true} | ${0} + ${true} | ${1} + ${false} | ${0} + `('Shows proper group name', ({ hasCostData, alerts }) => { + it('Shows group display name when available', async () => { + const rendered = await renderInTestApp( + + + , + ); + expect( + rendered.queryByText(/Test group display name/), + ).toBeInTheDocument(); + }); + + it('Fallbacks to group id when display name not available', async () => { + const rendered = await renderInTestApp( + + + , + ); + expect(rendered.queryByText(/test-user-group-1/)).toBeInTheDocument(); + }); + }); }); diff --git a/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.tsx b/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.tsx index cc68f79db1..540165d1d9 100644 --- a/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.tsx +++ b/plugins/cost-insights/src/components/CostInsightsHeader/CostInsightsHeader.tsx @@ -28,19 +28,20 @@ function useDisplayName(): string { } type CostInsightsHeaderProps = { - owner: string; + groupId: string; groups: Group[]; hasCostData: boolean; alerts: number; }; const CostInsightsHeaderNoData = ({ - owner, + groupId, groups, }: CostInsightsHeaderProps) => { const displayName = useDisplayName(); const classes = useCostInsightsStyles(); const hasMultipleGroups = groups.length > 1; + const ownerName = groups.find(({ id }) => id === groupId)?.name ?? groupId; return ( <> @@ -51,8 +52,8 @@ const CostInsightsHeaderNoData = ({ Well this is awkward - Hey, {displayName}! {owner} doesn't seem to have any cloud - costs. + Hey, {displayName}! {ownerName} doesn't seem to have any + cloud costs. {hasMultipleGroups && ( @@ -64,11 +65,13 @@ const CostInsightsHeaderNoData = ({ }; const CostInsightsHeaderAlerts = ({ - owner, + groupId, + groups, alerts, }: CostInsightsHeaderProps) => { const displayName = useDisplayName(); const classes = useCostInsightsStyles(); + const ownerName = groups.find(({ id }) => id === groupId)?.name ?? groupId; return ( <> @@ -81,15 +84,19 @@ const CostInsightsHeaderAlerts = ({ Hey, {displayName}! We've identified{' '} {alerts > 1 ? 'a few things ' : 'one thing '} - {owner} should look into next. + {ownerName} should look into next. ); }; -const CostInsightsHeaderNoAlerts = ({ owner }: CostInsightsHeaderProps) => { +const CostInsightsHeaderNoAlerts = ({ + groupId, + groups, +}: CostInsightsHeaderProps) => { const displayName = useDisplayName(); const classes = useCostInsightsStyles(); + const ownerName = groups.find(({ id }) => id === groupId)?.name ?? groupId; return ( <> @@ -100,7 +107,7 @@ const CostInsightsHeaderNoAlerts = ({ owner }: CostInsightsHeaderProps) => { Your team is doing great - Hey, {displayName}! {owner} is doing well. No major + Hey, {displayName}! {ownerName} is doing well. No major changes this month. diff --git a/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx b/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx index db5666768e..00d92f945d 100644 --- a/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx +++ b/plugins/cost-insights/src/components/CostInsightsPage/CostInsightsPage.tsx @@ -84,6 +84,7 @@ export const CostInsightsPage = () => { const accepted = useMemo(() => alerts.filter(isAlertAccepted), [alerts]); const dismissed = useMemo(() => alerts.filter(isAlertDismissed), [alerts]); + const isProductsDisplayed = !!config.products?.length; const isActionItemsDisplayed = !!active.length; const isAlertInsightsDisplayed = !!alerts.length; @@ -247,14 +248,16 @@ export const CostInsightsPage = () => { return ( - - - - - + {(isProductsDisplayed || isActionItemsDisplayed) && ( + + + + + + )} { { - {!isAlertInsightsDisplayed && } - - - - - + {!isAlertInsightsDisplayed && isProductsDisplayed && } + {isProductsDisplayed && ( + + + + + + )} diff --git a/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.test.tsx b/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.test.tsx index 6da6286515..2e2131daff 100644 --- a/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.test.tsx +++ b/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.test.tsx @@ -32,6 +32,7 @@ const mockGroups: Group[] = [ }, { id: 'test-group-3', + name: 'Test Group 3', }, ]; @@ -76,7 +77,7 @@ describe('', () => { ); await userEvent.click(rendered.getByTestId('cost-insights-groups-tab')); mockGroups.forEach(group => - expect(rendered.getByText(group.id)).toBeInTheDocument(), + expect(rendered.getByText(group.name ?? group.id)).toBeInTheDocument(), ); }); }); diff --git a/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.tsx b/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.tsx index 3bb3f14214..935184ee55 100644 --- a/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.tsx +++ b/plugins/cost-insights/src/components/CostInsightsTabs/CostInsightsTabs.tsx @@ -100,7 +100,7 @@ export const CostInsightsTabs = ({ groups }: CostInsightsTabsProps) => { data-testid={g.id} onClick={updateGroupFilterAndCloseMenu(g)} > - {g.id} + {g.name ?? g.id} ))} diff --git a/plugins/cost-insights/src/example/client.ts b/plugins/cost-insights/src/example/client.ts index a7a2a0e22f..a6aadedd09 100644 --- a/plugins/cost-insights/src/example/client.ts +++ b/plugins/cost-insights/src/example/client.ts @@ -52,7 +52,8 @@ export class ExampleCostInsightsClient implements CostInsightsApi { async getUserGroups(userId: string): Promise { const groups: Group[] = await this.request({ userId }, [ - { id: 'pied-piper' }, + { id: 'group-a', name: 'Group A' }, + { id: 'group-b', name: 'Group B' }, ]); return groups; diff --git a/plugins/cost-insights/src/hooks/useConfig.tsx b/plugins/cost-insights/src/hooks/useConfig.tsx index 451a48b71f..236c142b3b 100644 --- a/plugins/cost-insights/src/hooks/useConfig.tsx +++ b/plugins/cost-insights/src/hooks/useConfig.tsx @@ -85,12 +85,15 @@ export const ConfigProvider = ({ children }: PropsWithChildren<{}>) => { useEffect(() => { function getProducts(): Product[] { - const products = c.getConfig('costInsights.products'); - return products.keys().map(key => ({ - kind: key, - name: products.getString(`${key}.name`), - aggregation: [0, 0], - })); + const products = c.getOptionalConfig('costInsights.products'); + if (products) { + return products.keys().map(key => ({ + kind: key, + name: products.getString(`${key}.name`), + aggregation: [0, 0], + })); + } + return []; } function getMetrics(): Metric[] { @@ -122,13 +125,14 @@ export const ConfigProvider = ({ children }: PropsWithChildren<{}>) => { } function getIcons(): Icon[] { - const products = c.getConfig('costInsights.products'); - const keys = products.keys(); - - return keys.map(k => ({ - kind: k, - component: getIcon(products.getOptionalString(`${k}.icon`)), - })); + const products = c.getOptionalConfig('costInsights.products'); + if (products) { + return products.keys().map(k => ({ + kind: k, + component: getIcon(products.getOptionalString(`${k}.icon`)), + })); + } + return []; } function getEngineerCost(): number { diff --git a/plugins/cost-insights/src/hooks/useLoading.tsx b/plugins/cost-insights/src/hooks/useLoading.tsx index 25599db58e..84828491de 100644 --- a/plugins/cost-insights/src/hooks/useLoading.tsx +++ b/plugins/cost-insights/src/hooks/useLoading.tsx @@ -21,6 +21,7 @@ import React, { SetStateAction, useContext, useEffect, + useMemo, useReducer, useState, } from 'react'; @@ -32,6 +33,7 @@ import { INITIAL_LOADING_ACTIONS, } from '../utils/loading'; import { useBackdropStyles as useStyles } from '../utils/styles'; +import { useConfig } from './useConfig'; export type LoadingContextProps = { state: Loading; @@ -54,7 +56,16 @@ function reducer(prevState: Loading, action: Partial): Loading { export const LoadingProvider = ({ children }: PropsWithChildren<{}>) => { const classes = useStyles(); - const actions = INITIAL_LOADING_ACTIONS; + const { products } = useConfig(); + const actions = useMemo( + () => + INITIAL_LOADING_ACTIONS.filter( + action => + products.length || + action !== DefaultLoadingAction.CostInsightsProducts, + ), + [products], + ); const [state, dispatch] = useReducer(reducer, getDefaultState(actions)); const [isBackdropVisible, setBackdropVisible] = useState(false); diff --git a/plugins/cost-insights/src/utils/formatters.test.ts b/plugins/cost-insights/src/utils/formatters.test.ts index 9fe17f277f..8bf0a6a9d7 100644 --- a/plugins/cost-insights/src/utils/formatters.test.ts +++ b/plugins/cost-insights/src/utils/formatters.test.ts @@ -73,6 +73,9 @@ describe.each` ${0.123123} | ${'12%'} ${1.123} | ${'112%'} ${10.123} | ${'>1000%'} + ${-0.123123} | ${'-12%'} + ${-1.123} | ${'-112%'} + ${-10.123} | ${'>-1000%'} `('formatPercent', ({ ratio, expected }) => { it(`correctly formats ${ratio} as ${expected}`, () => { expect(formatPercent(ratio)).toBe(expected); diff --git a/plugins/cost-insights/src/utils/formatters.ts b/plugins/cost-insights/src/utils/formatters.ts index 70782123cd..e9b19097a4 100644 --- a/plugins/cost-insights/src/utils/formatters.ts +++ b/plugins/cost-insights/src/utils/formatters.ts @@ -81,9 +81,17 @@ export function formatCurrency(amount: number, currency?: string): string { return currency ? `${numString} ${pluralize(currency, n)}` : numString; } -export function formatChange(change: ChangeStatistic): string { +export function formatChange( + change: ChangeStatistic, + options?: { absolute: boolean }, +): string { if (notEmpty(change.ratio)) { - return formatPercent(Math.abs(change.ratio)); + return formatPercent( + options?.absolute ? Math.abs(change.ratio) : change.ratio, + ); + } + if (options?.absolute) { + return '∞'; } return change.amount >= 0 ? '∞' : '-∞'; } @@ -95,7 +103,7 @@ export function formatPercent(n: number): string { } if (Math.abs(n) > 10) { - return `>1000%`; + return `>${n < 0 ? '-' : ''}1000%`; } return `${(n * 100).toFixed(0)}%`; diff --git a/plugins/dynatrace/CHANGELOG.md b/plugins/dynatrace/CHANGELOG.md index cfa95d5fb2..08a98daa2e 100644 --- a/plugins/dynatrace/CHANGELOG.md +++ b/plugins/dynatrace/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-dynatrace +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.1 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + ## 0.1.1-next.3 ### Patch Changes diff --git a/plugins/dynatrace/README.md b/plugins/dynatrace/README.md index 150c9768af..8ed72ebb5d 100644 --- a/plugins/dynatrace/README.md +++ b/plugins/dynatrace/README.md @@ -38,6 +38,8 @@ dynatrace: #### Catalog Configuration +##### View Recent Application Problems + To show information from Dynatrace for a catalog entity, add the following annotation to `catalog-info.yaml`: ```yaml @@ -51,6 +53,23 @@ metadata: The `DYNATRACE_ENTITY_ID` can be found in Dynatrace by browsing to the entity (a service, synthetic, frontend, workload, etc.). It will be located in the browser address bar in the `id` parameter and has the format `ENTITY_TYPE-ENTITY_ID`, where `ENTITY_TYPE` will be one of `SERVICE`, `SYNTHETIC_TEST`, or other, and `ENTITY_ID` will be a string of characters containing uppercase letters and numbers. +##### Viewing Recent Synthetics Results + +To show recent results from a Synthetic Monitor, add the following annotation to `catalog-info.yaml`: + +```yaml +# catalog-info.yaml +# [...] +metadata: + annotations: + dynatrace.com/synthetics-ids: SYNTHETIC_ID, SYNTHETIC_ID_2, ... +# [...] +``` + +The annotation can also contain a comma or space separated list of Synthetic Ids to surface details for multiple monitors! + +The `SYNTHETIC_ID` can be found in Dynatrace by browsing to the Synthetic monitor. It will be located in the browser address bar in the resource path - `https://example.dynatrace.com/ui/http-monitor/HTTP_CHECK-1234` for an Http check, or `https://example.dynatrace.com/ui/browser-monitor/SYNTHETIC_TEST-1234` for a browser clickpath. + ## Disclaimer This plugin is not officially supported by Dynatrace. diff --git a/plugins/dynatrace/api-report.md b/plugins/dynatrace/api-report.md index 026df62189..59fd145250 100644 --- a/plugins/dynatrace/api-report.md +++ b/plugins/dynatrace/api-report.md @@ -9,7 +9,7 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; // @public -export const dynatracePlugin: BackstagePlugin<{}, {}>; +export const dynatracePlugin: BackstagePlugin<{}, {}, {}>; // @public export const DynatraceTab: () => JSX.Element; diff --git a/plugins/dynatrace/package.json b/plugins/dynatrace/package.json index 8862bbf548..3ae4d60bc1 100644 --- a/plugins/dynatrace/package.json +++ b/plugins/dynatrace/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-dynatrace", - "version": "0.1.1-next.3", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,10 +22,10 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -33,14 +33,14 @@ "react-use": "^17.2.4" }, "peerDependencies": { - "@backstage/plugin-catalog-react": "^1.1.2-next.0", + "@backstage/plugin-catalog-react": "^1.1.3-next.0", "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", @@ -48,7 +48,7 @@ "@types/node": "*", "cross-fetch": "^3.1.5", "express": "^4.18.1", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/dynatrace/src/api/DynatraceApi.ts b/plugins/dynatrace/src/api/DynatraceApi.ts index 1865b20363..4cb5f105bf 100644 --- a/plugins/dynatrace/src/api/DynatraceApi.ts +++ b/plugins/dynatrace/src/api/DynatraceApi.ts @@ -35,8 +35,32 @@ export type DynatraceProblem = { affectedEntities: Array; }; +type SyntheticRequestResults = { + startTimestamp: number; +}; + +export interface DynatraceSyntheticResults { + monitorId: string; + locationsExecutionResults: [ + { + locationId: number; + executionId: string; + requestResults: Array; + }, + ]; +} + +export interface DynatraceSyntheticLocationInfo { + entityId: string; + name: string; + city: string; + browserType: string; +} + export interface DynatraceProblems { problems: Array; + totalCount: number; + pageSize: number; } export const dynatraceApiRef = createApiRef({ @@ -47,4 +71,10 @@ export type DynatraceApi = { getDynatraceProblems( dynatraceEntityId: string, ): Promise; + getDynatraceSyntheticFailures( + syntheticsId: string, + ): Promise; + getDynatraceSyntheticLocationInfo( + syntheticLocationId: string, + ): Promise; }; diff --git a/plugins/dynatrace/src/api/DynatraceClient.ts b/plugins/dynatrace/src/api/DynatraceClient.ts index 27476ddbac..a31253bcb5 100644 --- a/plugins/dynatrace/src/api/DynatraceClient.ts +++ b/plugins/dynatrace/src/api/DynatraceClient.ts @@ -13,7 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { DynatraceProblems, DynatraceApi } from './DynatraceApi'; +import { + DynatraceProblems, + DynatraceApi, + DynatraceSyntheticResults, + DynatraceSyntheticLocationInfo, +} from './DynatraceApi'; import { DiscoveryApi, FetchApi } from '@backstage/core-plugin-api'; export class DynatraceClient implements DynatraceApi { @@ -52,11 +57,37 @@ export class DynatraceClient implements DynatraceApi { ); } + async getDynatraceSyntheticFailures( + syntheticsId: string, + ): Promise { + if (!syntheticsId) { + throw new Error('Dynatrace syntheticId is required'); + } + + return this.callApi( + `synthetic/execution/${encodeURIComponent(syntheticsId)}/FAILED`, + {}, + ); + } + + async getDynatraceSyntheticLocationInfo( + syntheticLocationId: string, + ): Promise { + if (!syntheticLocationId) { + throw new Error('Dynatrace syntheticLocationId is required'); + } + + return this.callApi( + `synthetic/locations/${encodeURIComponent(syntheticLocationId)}`, + {}, + ); + } + async getDynatraceProblems( dynatraceEntityId: string, ): Promise { if (!dynatraceEntityId) { - throw new Error('Dynatrace entity ID is required'); + throw new Error('Dynatrace entity id is required'); } return this.callApi('problems', { diff --git a/plugins/dynatrace/src/components/DynatraceTab/DynatraceTab.tsx b/plugins/dynatrace/src/components/DynatraceTab/DynatraceTab.tsx index c284eaba0f..3f58eed9dc 100644 --- a/plugins/dynatrace/src/components/DynatraceTab/DynatraceTab.tsx +++ b/plugins/dynatrace/src/components/DynatraceTab/DynatraceTab.tsx @@ -18,14 +18,16 @@ import { Grid } from '@material-ui/core'; import { Page, Content, - ContentHeader, - SupportButton, MissingAnnotationEmptyState, } from '@backstage/core-components'; import { useEntity } from '@backstage/plugin-catalog-react'; import { ProblemsList } from '../Problems/ProblemsList'; +import { SyntheticsCard } from '../Synthetics/SyntheticsCard'; import { isDynatraceAvailable } from '../../plugin'; -import { DYNATRACE_ID_ANNOTATION } from '../../constants'; +import { + DYNATRACE_ID_ANNOTATION, + DYNATRACE_SYNTHETICS_ANNOTATION, +} from '../../constants'; export const DynatraceTab = () => { const { entity } = useEntity(); @@ -37,18 +39,30 @@ export const DynatraceTab = () => { const dynatraceEntityId: string = entity?.metadata.annotations?.[DYNATRACE_ID_ANNOTATION]!; + const syntheticsIds: string = + entity?.metadata.annotations?.[DYNATRACE_SYNTHETICS_ANNOTATION]!; + return ( - - - Plugin to show information from Dynatrace - - - - - + {dynatraceEntityId ? ( + + + + ) : ( + '' + )} + {syntheticsIds + ?.split(/[ ,]/) + .filter(Boolean) + .map(id => { + return ( + + + + ); + })} diff --git a/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.test.tsx b/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.test.tsx index 1249f4e886..9b9c51dca1 100644 --- a/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.test.tsx +++ b/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.test.tsx @@ -36,12 +36,12 @@ describe('ProblemStatus', () => { .mockResolvedValue({ problems }); const rendered = await renderInTestApp( - + , ); expect(await rendered.findByText('example-service')).toBeInTheDocument(); }); - it('renders "nothing to report :)" if no problems are found', async () => { + it('returns "No Problems to Report!" if no problems are found', async () => { mockDynatraceApi.getDynatraceProblems = jest.fn().mockResolvedValue({}); const rendered = await renderInTestApp( @@ -49,7 +49,7 @@ describe('ProblemStatus', () => { , ); expect( - await rendered.findByText('Nothing to report :)'), + await rendered.findByText('No Problems to Report!'), ).toBeInTheDocument(); }); }); diff --git a/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.tsx b/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.tsx index ac69abf93e..2ee0dda48d 100644 --- a/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.tsx +++ b/plugins/dynatrace/src/components/Problems/ProblemsList/ProblemsList.tsx @@ -15,19 +15,40 @@ */ import React from 'react'; import useAsync from 'react-use/lib/useAsync'; -import { Progress } from '@backstage/core-components'; -import Alert from '@material-ui/lab/Alert'; -import { useApi } from '@backstage/core-plugin-api'; +import { + Progress, + ResponseErrorPanel, + EmptyState, +} from '@backstage/core-components'; +import { useApi, configApiRef } from '@backstage/core-plugin-api'; import { ProblemsTable } from '../ProblemsTable'; -import { dynatraceApiRef } from '../../../api'; +import { dynatraceApiRef, DynatraceProblem } from '../../../api'; +import { InfoCard } from '@backstage/core-components'; type ProblemsListProps = { dynatraceEntityId: string; }; +const cardContents = ( + problems: DynatraceProblem[], + dynatraceBaseUrl: string, +) => { + return problems.length ? ( + + ) : ( + + ); +}; + export const ProblemsList = (props: ProblemsListProps) => { const { dynatraceEntityId } = props; + const configApi = useApi(configApiRef); const dynatraceApi = useApi(dynatraceApiRef); + const dynatraceBaseUrl = configApi.getString('dynatrace.baseUrl'); + const { value, loading, error } = useAsync(async () => { return dynatraceApi.getDynatraceProblems(dynatraceEntityId); }, [dynatraceApi, dynatraceEntityId]); @@ -36,8 +57,18 @@ export const ProblemsList = (props: ProblemsListProps) => { if (loading) { return ; } else if (error) { - return {error.message}; + return ; } - if (!problems) return
Nothing to report :)
; - return ; + return ( + + {cardContents(problems || [], dynatraceBaseUrl)} + + ); }; diff --git a/plugins/dynatrace/src/components/Problems/ProblemsTable/ProblemsTable.test.tsx b/plugins/dynatrace/src/components/Problems/ProblemsTable/ProblemsTable.test.tsx index e4adc43656..aaa3ea0024 100644 --- a/plugins/dynatrace/src/components/Problems/ProblemsTable/ProblemsTable.test.tsx +++ b/plugins/dynatrace/src/components/Problems/ProblemsTable/ProblemsTable.test.tsx @@ -28,17 +28,9 @@ describe('ProblemsTable', () => { it('renders the table with some problem data', async () => { const rendered = await renderInTestApp( - , + , , ); - expect(await rendered.findByText('example-service')).toBeInTheDocument(); - }); - it('renders an empty table when no data is provided', async () => { - const rendered = await renderInTestApp( - - - , - ); - expect(await rendered.findByText('Problems')).toBeInTheDocument(); + expect(await rendered.findByTitle('Search')).toBeInTheDocument(); }); }); diff --git a/plugins/dynatrace/src/components/Problems/ProblemsTable/ProblemsTable.tsx b/plugins/dynatrace/src/components/Problems/ProblemsTable/ProblemsTable.tsx index 8e3d330c37..78d26e3fe2 100644 --- a/plugins/dynatrace/src/components/Problems/ProblemsTable/ProblemsTable.tsx +++ b/plugins/dynatrace/src/components/Problems/ProblemsTable/ProblemsTable.tsx @@ -17,17 +17,19 @@ import React from 'react'; import { Table, TableColumn } from '@backstage/core-components'; import { DynatraceProblem } from '../../../api/DynatraceApi'; import { ProblemStatus } from '../ProblemStatus'; -import { configApiRef } from '@backstage/core-plugin-api'; -import { useApi } from '@backstage/core-plugin-api'; import { Link } from '@material-ui/core'; type ProblemsTableProps = { problems: DynatraceProblem[]; + dynatraceBaseUrl: string; }; -export const ProblemsTable = ({ problems }: ProblemsTableProps) => { - const configApi = useApi(configApiRef); - const dynatraceBaseUrl = configApi.getString('dynatrace.baseUrl'); +const parseTimestamp = (timestamp: number | undefined) => { + return timestamp ? new Date(timestamp).toLocaleString() : 'N/A'; +}; + +export const ProblemsTable = (props: ProblemsTableProps) => { + const { problems, dynatraceBaseUrl } = props; const columns: TableColumn[] = [ { title: 'Title', @@ -62,20 +64,18 @@ export const ProblemsTable = ({ problems }: ProblemsTableProps) => { { title: 'Start Time', field: 'startTime', - render: (row: Partial) => - new Date(row.startTime || 0).toString(), + render: (row: Partial) => parseTimestamp(row.startTime), }, { title: 'End Time', field: 'endTime', render: (row: Partial) => - row.endTime === -1 ? 'ongoing' : new Date(row.endTime || 0).toString(), + row.endTime === -1 ? 'ongoing' : parseTimestamp(row.endTime), }, ]; return ( { diff --git a/plugins/dynatrace/src/components/Synthetics/SyntheticsCard/SyntheticsCard.test.tsx b/plugins/dynatrace/src/components/Synthetics/SyntheticsCard/SyntheticsCard.test.tsx new file mode 100644 index 0000000000..e9083a3f82 --- /dev/null +++ b/plugins/dynatrace/src/components/Synthetics/SyntheticsCard/SyntheticsCard.test.tsx @@ -0,0 +1,52 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { SyntheticsCard } from './SyntheticsCard'; +import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; +import { dynatraceApiRef } from '../../../api'; +import { ApiProvider, ConfigReader } from '@backstage/core-app-api'; +import { configApiRef } from '@backstage/core-plugin-api'; + +const mockDynatraceApi = { + getDynatraceSyntheticFailures: jest.fn(), +}; +const apis = TestApiRegistry.from( + [dynatraceApiRef, mockDynatraceApi], + [configApiRef, new ConfigReader({ dynatrace: { baseUrl: '__dynatrace__' } })], +); + +describe('SyntheticsCard', () => { + it('renders the card with Synthetics data', async () => { + mockDynatraceApi.getDynatraceSyntheticFailures = jest + .fn() + .mockResolvedValue({ + locationsExecutionResults: [ + { + locationId: '__location__', + requestResults: [{ startTimestamp: 0 }], + }, + ], + }); + const rendered = await renderInTestApp( + + , + , + ); + expect( + await rendered.findByText('View this Synthetic in Dynatrace'), + ).toBeInTheDocument(); + }); +}); diff --git a/plugins/dynatrace/src/components/Synthetics/SyntheticsCard/SyntheticsCard.tsx b/plugins/dynatrace/src/components/Synthetics/SyntheticsCard/SyntheticsCard.tsx new file mode 100644 index 0000000000..6b51a1725c --- /dev/null +++ b/plugins/dynatrace/src/components/Synthetics/SyntheticsCard/SyntheticsCard.tsx @@ -0,0 +1,88 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import useAsync from 'react-use/lib/useAsync'; +import { Progress, ResponseErrorPanel } from '@backstage/core-components'; +import { InfoCard } from '@backstage/core-components'; +import { useApi, configApiRef } from '@backstage/core-plugin-api'; +import { dynatraceApiRef } from '../../../api'; +import { SyntheticsLocation } from '../SyntheticsLocation'; + +type SyntheticsCardProps = { + syntheticsId: string; +}; + +const dynatraceMonitorPrefixes = (idPrefix: string): string => { + switch (idPrefix) { + case 'HTTP_CHECK': + return 'ui/http-monitor'; + case 'BROWSER_MONITOR': + return 'ui/browser-monitor'; + case 'SYNTHETIC_TEST': + return 'ui/browser-monitor'; + default: + throw new Error('Invalid synthetic Id'); + } +}; + +export const SyntheticsCard = (props: SyntheticsCardProps) => { + const { syntheticsId } = props; + const configApi = useApi(configApiRef); + const dynatraceApi = useApi(dynatraceApiRef); + const dynatraceBaseUrl = configApi.getString('dynatrace.baseUrl'); + + const { value, loading, error } = useAsync(async () => { + return dynatraceApi.getDynatraceSyntheticFailures(syntheticsId); + }, [dynatraceApi, syntheticsId]); + + if (loading) { + return ; + } else if (error) { + return ; + } + + const deepLinkPrefix = dynatraceMonitorPrefixes( + `${syntheticsId.split('-')[0]}`, + ); + + const lastFailed = value?.locationsExecutionResults.map(l => { + return { + timestamp: l.requestResults[0].startTimestamp, + location: Number(l.locationId).toString(16), + }; + }); + + return ( + + {lastFailed?.map(l => { + return ( + + ); + })} + + ); +}; diff --git a/plugins/dynatrace/src/components/Synthetics/SyntheticsCard/index.ts b/plugins/dynatrace/src/components/Synthetics/SyntheticsCard/index.ts new file mode 100644 index 0000000000..5284e0cfab --- /dev/null +++ b/plugins/dynatrace/src/components/Synthetics/SyntheticsCard/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { SyntheticsCard } from './SyntheticsCard'; diff --git a/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/SyntheticsLocation.test.tsx b/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/SyntheticsLocation.test.tsx new file mode 100644 index 0000000000..de04f73e36 --- /dev/null +++ b/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/SyntheticsLocation.test.tsx @@ -0,0 +1,65 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { SyntheticsLocation } from './SyntheticsLocation'; +import { renderInTestApp, TestApiRegistry } from '@backstage/test-utils'; +import { dynatraceApiRef } from '../../../api'; +import { ApiProvider, ConfigReader } from '@backstage/core-app-api'; +import { configApiRef } from '@backstage/core-plugin-api'; + +const mockDynatraceApi = { + getDynatraceSyntheticLocationInfo: jest.fn(), +}; +const apis = TestApiRegistry.from( + [dynatraceApiRef, mockDynatraceApi], + [configApiRef, new ConfigReader({ dynatrace: { baseUrl: '__dynatrace__' } })], +); + +describe('SyntheticsLocation', () => { + it('renders the SyntheticsLocation chip - recent failure', async () => { + mockDynatraceApi.getDynatraceSyntheticLocationInfo = jest + .fn() + .mockResolvedValue({ name: '__location__' }); + const rendered = await renderInTestApp( + + + , + , + ); + expect(await rendered.findByText(/failed/)).toBeInTheDocument(); + }); + it('renders the SyntheticsLocation chip - no failures', async () => { + mockDynatraceApi.getDynatraceSyntheticLocationInfo = jest + .fn() + .mockResolvedValue({ name: '__location__' }); + const rendered = await renderInTestApp( + + + , + , + ); + expect(await rendered.findByText(/__location__/)).toBeInTheDocument(); + expect(await rendered.queryByText(/failed/)).not.toBeInTheDocument(); + }); +}); diff --git a/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/SyntheticsLocation.tsx b/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/SyntheticsLocation.tsx new file mode 100644 index 0000000000..4d328210cb --- /dev/null +++ b/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/SyntheticsLocation.tsx @@ -0,0 +1,75 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import React from 'react'; +import useAsync from 'react-use/lib/useAsync'; +import { Progress, ResponseErrorPanel } from '@backstage/core-components'; +import { useApi } from '@backstage/core-plugin-api'; +import { Chip } from '@material-ui/core'; +import { dynatraceApiRef } from '../../../api'; + +type SyntheticsLocationProps = { + lastFailedTimestamp: Date; + locationId: string; + key: string; +}; + +const failedInLastXHours = (timestamp: Date, offset: number): boolean => { + if (offset < 0 || offset > 24) + throw new Error('offset must be between 0 and 24'); + return timestamp > new Date(new Date().getTime() - 1000 * 60 * 60 * offset); +}; + +const chipColor = (timestamp: Date): string => { + if (failedInLastXHours(timestamp, 1)) { + return 'salmon'; + } + if (failedInLastXHours(timestamp, 6)) { + return 'sandybrown'; + } + if (failedInLastXHours(timestamp, 24)) { + return 'palegoldenrod'; + } + return 'lightgreen'; +}; + +export const SyntheticsLocation = (props: SyntheticsLocationProps) => { + const { lastFailedTimestamp, locationId } = props; + const dynatraceApi = useApi(dynatraceApiRef); + const { value, loading, error } = useAsync(async () => { + return dynatraceApi.getDynatraceSyntheticLocationInfo( + `SYNTHETIC_LOCATION-00000000000000${locationId}`, + ); + }); + + if (loading) { + return ; + } else if (error) { + return ; + } + + return ( + + ); +}; diff --git a/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/index.ts b/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/index.ts new file mode 100644 index 0000000000..1dc8a783fe --- /dev/null +++ b/plugins/dynatrace/src/components/Synthetics/SyntheticsLocation/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { SyntheticsLocation } from './SyntheticsLocation'; diff --git a/plugins/dynatrace/src/constants.ts b/plugins/dynatrace/src/constants.ts index 21453e0338..c4cc48d48a 100644 --- a/plugins/dynatrace/src/constants.ts +++ b/plugins/dynatrace/src/constants.ts @@ -14,3 +14,4 @@ * limitations under the License. */ export const DYNATRACE_ID_ANNOTATION = 'dynatrace.com/dynatrace-entity-id'; +export const DYNATRACE_SYNTHETICS_ANNOTATION = 'dynatrace.com/synthetics-ids'; diff --git a/plugins/dynatrace/src/mocks/problems.json b/plugins/dynatrace/src/mocks/problems.json index b1894bef56..16e3e156ec 100644 --- a/plugins/dynatrace/src/mocks/problems.json +++ b/plugins/dynatrace/src/mocks/problems.json @@ -1,5 +1,5 @@ { - "totalCount": 0, + "totalCount": 1, "pageSize": 0, "nextPageKey": "AQAAABQBAAAABQ==", "problems": [ diff --git a/plugins/dynatrace/src/plugin.ts b/plugins/dynatrace/src/plugin.ts index fc1778b45c..26ecb1aba1 100644 --- a/plugins/dynatrace/src/plugin.ts +++ b/plugins/dynatrace/src/plugin.ts @@ -23,7 +23,10 @@ import { } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; -import { DYNATRACE_ID_ANNOTATION } from './constants'; +import { + DYNATRACE_ID_ANNOTATION, + DYNATRACE_SYNTHETICS_ANNOTATION, +} from './constants'; import { rootRouteRef } from './routes'; @@ -55,7 +58,8 @@ export const dynatracePlugin = createPlugin({ * @param entity {Entity} - The entity to check for the dynatrace id annotation. */ export const isDynatraceAvailable = (entity: Entity) => - Boolean(entity.metadata.annotations?.[DYNATRACE_ID_ANNOTATION]); + Boolean(entity.metadata.annotations?.[DYNATRACE_ID_ANNOTATION]) || + Boolean(entity.metadata.annotations?.[DYNATRACE_SYNTHETICS_ANNOTATION]); /** * Creates a routable extension for the dynatrace plugin tab. diff --git a/plugins/example-todo-list-backend/CHANGELOG.md b/plugins/example-todo-list-backend/CHANGELOG.md index 4609c6c4ea..d541b6e65d 100644 --- a/plugins/example-todo-list-backend/CHANGELOG.md +++ b/plugins/example-todo-list-backend/CHANGELOG.md @@ -1,5 +1,30 @@ # @internal/plugin-todo-list-backend +## 1.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-auth-node@0.2.4 + +## 1.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-auth-node@0.2.4-next.0 + +## 1.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-auth-node@0.2.3 + - @backstage/errors@1.1.0 + ## 1.0.3-next.1 ### Patch Changes diff --git a/plugins/example-todo-list-backend/package.json b/plugins/example-todo-list-backend/package.json index 5be65f78b5..8b3e7877c5 100644 --- a/plugins/example-todo-list-backend/package.json +++ b/plugins/example-todo-list-backend/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-backend", - "version": "1.0.3-next.1", + "version": "1.0.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,10 +23,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.1", + "@backstage/backend-common": "^0.15.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-auth-node": "^0.2.3-next.1", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-auth-node": "^0.2.4", "@types/express": "^4.17.6", "cross-fetch": "^3.1.5", "express": "^4.17.1", @@ -36,10 +36,10 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.1", + "@backstage/cli": "^0.18.1", "@types/supertest": "^2.0.8", "@types/uuid": "^8.0.0", - "msw": "^0.44.0", + "msw": "^0.45.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/example-todo-list-common/CHANGELOG.md b/plugins/example-todo-list-common/CHANGELOG.md index ba6a7bcf3d..d624c2f6a6 100644 --- a/plugins/example-todo-list-common/CHANGELOG.md +++ b/plugins/example-todo-list-common/CHANGELOG.md @@ -1,5 +1,12 @@ # @internal/plugin-todo-list-common +## 1.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-permission-common@0.6.3 + ## 1.0.3-next.0 ### Patch Changes diff --git a/plugins/example-todo-list-common/package.json b/plugins/example-todo-list-common/package.json index 3d4fb5659e..0783ec5641 100644 --- a/plugins/example-todo-list-common/package.json +++ b/plugins/example-todo-list-common/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list-common", - "version": "1.0.3-next.0", + "version": "1.0.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -23,15 +23,15 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/plugin-permission-common": "^0.6.3-next.0" + "@backstage/plugin-permission-common": "^0.6.3" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.1", - "@backstage/core-app-api": "^1.0.4-next.0", - "@backstage/dev-utils": "^1.0.4-next.1", - "@backstage/test-utils": "^1.1.2-next.1", + "@backstage/cli": "^0.18.1-next.0", + "@backstage/core-app-api": "^1.0.5-next.0", + "@backstage/dev-utils": "^1.0.5-next.0", + "@backstage/test-utils": "^1.1.3-next.0", "@types/node": "^16.11.26", - "msw": "^0.44.0", + "msw": "^0.45.0", "cross-fetch": "^3.1.5" }, "files": [ diff --git a/plugins/example-todo-list/CHANGELOG.md b/plugins/example-todo-list/CHANGELOG.md index 054f814ea7..3d637910de 100644 --- a/plugins/example-todo-list/CHANGELOG.md +++ b/plugins/example-todo-list/CHANGELOG.md @@ -1,5 +1,37 @@ # @internal/plugin-todo-list +## 1.0.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 1.0.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 1.0.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 1.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + ## 1.0.3-next.3 ### Patch Changes diff --git a/plugins/example-todo-list/api-report.md b/plugins/example-todo-list/api-report.md index 534c33200e..68b3ffd73e 100644 --- a/plugins/example-todo-list/api-report.md +++ b/plugins/example-todo-list/api-report.md @@ -16,6 +16,7 @@ export const todoListPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; diff --git a/plugins/example-todo-list/package.json b/plugins/example-todo-list/package.json index d9ccb7f524..db168683a2 100644 --- a/plugins/example-todo-list/package.json +++ b/plugins/example-todo-list/package.json @@ -1,6 +1,6 @@ { "name": "@internal/plugin-todo-list", - "version": "1.0.3-next.3", + "version": "1.0.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,9 +24,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -36,16 +36,16 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/explore-react/CHANGELOG.md b/plugins/explore-react/CHANGELOG.md index 2cf0fb8402..b4c5547d9f 100644 --- a/plugins/explore-react/CHANGELOG.md +++ b/plugins/explore-react/CHANGELOG.md @@ -1,5 +1,28 @@ # @backstage/plugin-explore-react +## 0.0.20 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5 + +## 0.0.20-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + +## 0.0.19 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.4 + ## 0.0.19-next.0 ### Patch Changes diff --git a/plugins/explore-react/package.json b/plugins/explore-react/package.json index ecd57e4cf7..9a20b74af2 100644 --- a/plugins/explore-react/package.json +++ b/plugins/explore-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore-react", "description": "A frontend library for Backstage plugins that want to interact with the explore plugin", - "version": "0.0.19-next.0", + "version": "0.0.20", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,19 +33,19 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/core-plugin-api": "^1.0.4-next.0" + "@backstage/core-plugin-api": "^1.0.5" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/explore/CHANGELOG.md b/plugins/explore/CHANGELOG.md index e418b35069..96813c08ca 100644 --- a/plugins/explore/CHANGELOG.md +++ b/plugins/explore/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-explore +## 0.3.39 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-explore-react@0.0.20 + +## 0.3.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.3.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-explore-react@0.0.20-next.0 + +## 0.3.38 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-explore-react@0.0.19 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.3.38-next.3 ### Patch Changes diff --git a/plugins/explore/api-report.md b/plugins/explore/api-report.md index 412c0cc54b..f4c7345b6c 100644 --- a/plugins/explore/api-report.md +++ b/plugins/explore/api-report.md @@ -33,9 +33,7 @@ export const DomainCard: ({ entity }: DomainCardProps) => JSX.Element; // Warning: (ae-missing-release-tag) "DomainExplorerContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const DomainExplorerContent: ({ - title, -}: { +export const DomainExplorerContent: (props: { title?: string | undefined; }) => JSX.Element; @@ -68,7 +66,8 @@ const explorePlugin: BackstagePlugin< }, true >; - } + }, + {} >; export { explorePlugin }; export { explorePlugin as plugin }; @@ -81,18 +80,14 @@ export const exploreRouteRef: RouteRef; // Warning: (ae-missing-release-tag) "GroupsExplorerContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const GroupsExplorerContent: ({ - title, -}: { +export const GroupsExplorerContent: (props: { title?: string | undefined; }) => JSX.Element; // Warning: (ae-missing-release-tag) "ToolExplorerContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const ToolExplorerContent: ({ - title, -}: { +export const ToolExplorerContent: (props: { title?: string | undefined; }) => JSX.Element; diff --git a/plugins/explore/package.json b/plugins/explore/package.json index 0706739a42..9ac2c08e48 100644 --- a/plugins/explore/package.json +++ b/plugins/explore/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-explore", "description": "A Backstage plugin for building an exploration page of your software ecosystem", - "version": "0.3.38-next.3", + "version": "0.3.39", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,12 +34,12 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/plugin-explore-react": "^0.0.19-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/plugin-explore-react": "^0.0.20", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -53,17 +53,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.tsx b/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.tsx index ba495f6492..3cfed5b12b 100644 --- a/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.tsx +++ b/plugins/explore/src/components/DomainExplorerContent/DomainExplorerContent.tsx @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { DomainEntity } from '@backstage/catalog-model'; import { catalogApiRef } from '@backstage/plugin-catalog-react'; import { Button } from '@material-ui/core'; import React from 'react'; import useAsync from 'react-use/lib/useAsync'; import { DomainCard } from '../DomainCard'; - import { Content, ContentHeader, @@ -29,7 +29,6 @@ import { SupportButton, WarningPanel, } from '@backstage/core-components'; - import { useApi } from '@backstage/core-plugin-api'; const Body = () => { @@ -85,16 +84,11 @@ const Body = () => { ); }; -type DomainExplorerContentProps = { - title?: string; -}; - -export const DomainExplorerContent = ({ - title, -}: DomainExplorerContentProps) => { +/** @public */ +export const DomainExplorerContent = (props: { title?: string }) => { return ( - + Discover the domains in your ecosystem. diff --git a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx index ae711b85d9..62c4b093c0 100644 --- a/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx +++ b/plugins/explore/src/components/GroupsExplorerContent/GroupsExplorerContent.tsx @@ -31,21 +31,14 @@ const useStyles = makeStyles({ }, }); -type GroupsExplorerContentProps = { - title?: string; -}; - -export const GroupsExplorerContent = ({ - title, -}: GroupsExplorerContentProps) => { +export const GroupsExplorerContent = (props: { title?: string }) => { const classes = useStyles(); return ( - + Explore your groups. - ); diff --git a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx index db07bd0665..5404c67393 100644 --- a/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx +++ b/plugins/explore/src/components/ToolExplorerContent/ToolExplorerContent.tsx @@ -18,7 +18,6 @@ import { exploreToolsConfigRef } from '@backstage/plugin-explore-react'; import React from 'react'; import useAsync from 'react-use/lib/useAsync'; import { ToolCard } from '../ToolCard'; - import { Content, ContentHeader, @@ -28,7 +27,6 @@ import { SupportButton, WarningPanel, } from '@backstage/core-components'; - import { useApi } from '@backstage/core-plugin-api'; const Body = () => { @@ -68,13 +66,9 @@ const Body = () => { ); }; -type ToolExplorerContentProps = { - title?: string; -}; - -export const ToolExplorerContent = ({ title }: ToolExplorerContentProps) => ( +export const ToolExplorerContent = (props: { title?: string }) => ( - + Discover the tools in your ecosystem. diff --git a/plugins/firehydrant/CHANGELOG.md b/plugins/firehydrant/CHANGELOG.md index a53482fb2a..2af1f5ffe3 100644 --- a/plugins/firehydrant/CHANGELOG.md +++ b/plugins/firehydrant/CHANGELOG.md @@ -1,5 +1,44 @@ # @backstage/plugin-firehydrant +## 0.1.25 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.1.25-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.1.25-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.24 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.1.24-next.3 ### Patch Changes diff --git a/plugins/firehydrant/api-report.md b/plugins/firehydrant/api-report.md index 86f090c34d..c12048e81f 100644 --- a/plugins/firehydrant/api-report.md +++ b/plugins/firehydrant/api-report.md @@ -20,6 +20,7 @@ export const firehydrantPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; ``` diff --git a/plugins/firehydrant/package.json b/plugins/firehydrant/package.json index 9053ed4ed2..81d71c24c0 100644 --- a/plugins/firehydrant/package.json +++ b/plugins/firehydrant/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-firehydrant", "description": "A Backstage plugin that integrates towards FireHydrant", - "version": "0.1.24-next.3", + "version": "0.1.25", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -25,10 +25,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -39,17 +39,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/fossa/CHANGELOG.md b/plugins/fossa/CHANGELOG.md index 754f459449..8a7e37e0eb 100644 --- a/plugins/fossa/CHANGELOG.md +++ b/plugins/fossa/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-fossa +## 0.2.40 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.2.40-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.2.40-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.2.39 + +### Patch Changes + +- 322d1ceeba: Allow configuration of base URL for Fossa links +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.2.39-next.3 ### Patch Changes diff --git a/plugins/fossa/api-report.md b/plugins/fossa/api-report.md index d6e229d3d6..45f0746ac3 100644 --- a/plugins/fossa/api-report.md +++ b/plugins/fossa/api-report.md @@ -9,22 +9,14 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { InfoCardVariants } from '@backstage/core-components'; import { RouteRef } from '@backstage/core-plugin-api'; -// Warning: (ae-missing-release-tag) "EntityFossaCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityFossaCard: ({ - variant, -}: { +export const EntityFossaCard: (props: { variant?: InfoCardVariants | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "FossaPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const FossaPage: ({ entitiesFilter }: FossaPageProps) => JSX.Element; +export const FossaPage: (props: FossaPageProps) => JSX.Element; -// Warning: (ae-missing-release-tag) "FossaPageProps" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export type FossaPageProps = { entitiesFilter?: @@ -33,13 +25,12 @@ export type FossaPageProps = { | undefined; }; -// Warning: (ae-missing-release-tag) "fossaPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const fossaPlugin: BackstagePlugin< { fossaOverview: RouteRef; }, + {}, {} >; ``` diff --git a/plugins/fossa/package.json b/plugins/fossa/package.json index e22228061b..ccc98265b4 100644 --- a/plugins/fossa/package.json +++ b/plugins/fossa/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-fossa", "description": "A Backstage plugin that integrates towards FOSSA", - "version": "0.2.39-next.3", + "version": "0.2.40", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,12 +35,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -53,16 +53,16 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/fossa/src/components/FossaCard/FossaCard.tsx b/plugins/fossa/src/components/FossaCard/FossaCard.tsx index bbd5594fbc..31ff84e107 100644 --- a/plugins/fossa/src/components/FossaCard/FossaCard.tsx +++ b/plugins/fossa/src/components/FossaCard/FossaCard.tsx @@ -100,7 +100,9 @@ const Card = ({ ); }; -export const FossaCard = ({ variant }: { variant?: InfoCardVariants }) => { + +export const FossaCard = (props: { variant?: InfoCardVariants }) => { + const { variant } = props; const { entity } = useEntity(); const fossaApi = useApi(fossaApiRef); diff --git a/plugins/fossa/src/components/FossaPage/FossaPage.tsx b/plugins/fossa/src/components/FossaPage/FossaPage.tsx index 731852d4a7..faff862d0f 100644 --- a/plugins/fossa/src/components/FossaPage/FossaPage.tsx +++ b/plugins/fossa/src/components/FossaPage/FossaPage.tsx @@ -167,6 +167,7 @@ const filters: TableFilter[] = [ { column: 'Branch', type: 'select' }, ]; +/** @public */ export type FossaPageProps = { entitiesFilter?: | Record[] @@ -174,9 +175,8 @@ export type FossaPageProps = { | undefined; }; -export const FossaPage = ({ - entitiesFilter = { kind: 'Component' }, -}: FossaPageProps) => { +export const FossaPage = (props: FossaPageProps) => { + const { entitiesFilter = { kind: 'Component' } } = props; const catalogApi = useApi(catalogApiRef); const fossaApi = useApi(fossaApiRef); const [filter, setFilter] = useState(entitiesFilter); diff --git a/plugins/fossa/src/extensions.tsx b/plugins/fossa/src/extensions.tsx index 97bea6a4cf..d26057d9cc 100644 --- a/plugins/fossa/src/extensions.tsx +++ b/plugins/fossa/src/extensions.tsx @@ -21,6 +21,7 @@ import { createRoutableExtension, } from '@backstage/core-plugin-api'; +/** @public */ export const EntityFossaCard = fossaPlugin.provide( createComponentExtension({ name: 'EntityFossaCard', @@ -30,6 +31,7 @@ export const EntityFossaCard = fossaPlugin.provide( }), ); +/** @public */ export const FossaPage = fossaPlugin.provide( createRoutableExtension({ name: 'FossaPage', diff --git a/plugins/fossa/src/plugin.ts b/plugins/fossa/src/plugin.ts index 954ecedc81..bcc8c0f8e6 100644 --- a/plugins/fossa/src/plugin.ts +++ b/plugins/fossa/src/plugin.ts @@ -24,6 +24,7 @@ import { identityApiRef, } from '@backstage/core-plugin-api'; +/** @public */ export const fossaPlugin = createPlugin({ id: 'fossa', apis: [ diff --git a/plugins/gcalendar/CHANGELOG.md b/plugins/gcalendar/CHANGELOG.md index 93e4b1117b..946aae643a 100644 --- a/plugins/gcalendar/CHANGELOG.md +++ b/plugins/gcalendar/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-gcalendar +## 0.3.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.3.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.3.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.3.3 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.3.3-next.3 ### Patch Changes diff --git a/plugins/gcalendar/api-report.md b/plugins/gcalendar/api-report.md index b4aebf1ff3..61c39aaf2a 100644 --- a/plugins/gcalendar/api-report.md +++ b/plugins/gcalendar/api-report.md @@ -65,6 +65,7 @@ export const gcalendarPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; diff --git a/plugins/gcalendar/package.json b/plugins/gcalendar/package.json index ad111311c2..30f3a4f00d 100644 --- a/plugins/gcalendar/package.json +++ b/plugins/gcalendar/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-gcalendar", - "version": "0.3.3-next.3", + "version": "0.3.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -22,10 +22,10 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -43,10 +43,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", @@ -55,7 +55,7 @@ "@types/node": "^16.11.26", "@types/sanitize-html": "^2.6.2", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/gcp-projects/CHANGELOG.md b/plugins/gcp-projects/CHANGELOG.md index cd2be7a5f8..c7ab79eada 100644 --- a/plugins/gcp-projects/CHANGELOG.md +++ b/plugins/gcp-projects/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-gcp-projects +## 0.3.27 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.3.27-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.3.27-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.3.26 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 693990d4fe: Updated dependency `@react-hookz/web` to `^15.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + ## 0.3.26-next.3 ### Patch Changes diff --git a/plugins/gcp-projects/api-report.md b/plugins/gcp-projects/api-report.md index 8049441b1f..46c8dd2c2f 100644 --- a/plugins/gcp-projects/api-report.md +++ b/plugins/gcp-projects/api-report.md @@ -57,6 +57,7 @@ const gcpProjectsPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; export { gcpProjectsPlugin }; diff --git a/plugins/gcp-projects/package.json b/plugins/gcp-projects/package.json index 19c881a7fb..14c0b6ed15 100644 --- a/plugins/gcp-projects/package.json +++ b/plugins/gcp-projects/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-gcp-projects", "description": "A Backstage plugin that helps you manage projects in GCP", - "version": "0.3.26-next.3", + "version": "0.3.27", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,9 +34,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -47,17 +47,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/git-release-manager/CHANGELOG.md b/plugins/git-release-manager/CHANGELOG.md index be7c04d048..4613940252 100644 --- a/plugins/git-release-manager/CHANGELOG.md +++ b/plugins/git-release-manager/CHANGELOG.md @@ -1,5 +1,44 @@ # @backstage/plugin-git-release-manager +## 0.3.21 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.3.21-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.3.21-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.3.20 + +### Patch Changes + +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/theme@0.2.16 + ## 0.3.20-next.3 ### Patch Changes diff --git a/plugins/git-release-manager/api-report.md b/plugins/git-release-manager/api-report.md index 743ea4e0f9..d34b6c07fb 100644 --- a/plugins/git-release-manager/api-report.md +++ b/plugins/git-release-manager/api-report.md @@ -90,7 +90,6 @@ const DISABLE_CACHE: { const Divider: () => JSX.Element; // Warning: (ae-forgotten-export) The symbol "SemverTagParts" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "getBumpedSemverTagParts" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public function getBumpedSemverTagParts( @@ -105,14 +104,8 @@ function getBumpedSemverTagParts( }; }; -// Warning: (ae-missing-release-tag) "getBumpedTag" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public -function getBumpedTag({ - project, - tag, - bumpLevel, -}: { +function getBumpedTag(options: { project: Project; tag: string; bumpLevel: keyof typeof SEMVER_PARTS; @@ -167,10 +160,8 @@ function getSemverTagParts(tag: string): // @public (undocumented) function getShortCommitHash(hash: string): string; -// Warning: (ae-missing-release-tag) "getTagParts" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public -function getTagParts({ project, tag }: { project: Project; tag: string }): +function getTagParts(options: { project: Project; tag: string }): | { error: AlertError; tagParts?: undefined; @@ -203,17 +194,12 @@ export const gitReleaseManagerPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; -// Warning: (ae-missing-release-tag) "InfoCardPlus" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -const InfoCardPlus: ({ - children, -}: { - children?: React_2.ReactNode; -}) => JSX.Element; +const InfoCardPlus: (props: { children?: React_2.ReactNode }) => JSX.Element; // Warning: (ae-missing-release-tag) "internals" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -624,16 +610,8 @@ declare namespace testIds { export { TEST_IDS }; } -// Warning: (ae-missing-release-tag) "validateTagName" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -const validateTagName: ({ - project, - tagName, -}: { - project: Project; - tagName?: string | undefined; -}) => +const validateTagName: (options: { project: Project; tagName?: string }) => | { tagNameError: null; } @@ -652,9 +630,9 @@ const VERSIONING_STRATEGIES: { // Warnings were encountered during analysis: // // src/components/ResponseStepDialog/LinearProgressWithLabel.d.ts:5:5 - (ae-forgotten-export) The symbol "ResponseStep" needs to be exported by the entry point index.d.ts -// src/helpers/getBumpedTag.d.ts:14:5 - (ae-forgotten-export) The symbol "Project" needs to be exported by the entry point index.d.ts -// src/helpers/getBumpedTag.d.ts:19:5 - (ae-forgotten-export) The symbol "CalverTagParts" needs to be exported by the entry point index.d.ts -// src/helpers/getBumpedTag.d.ts:31:5 - (ae-forgotten-export) The symbol "AlertError" needs to be exported by the entry point index.d.ts +// src/helpers/getBumpedTag.d.ts:16:5 - (ae-forgotten-export) The symbol "Project" needs to be exported by the entry point index.d.ts +// src/helpers/getBumpedTag.d.ts:21:5 - (ae-forgotten-export) The symbol "CalverTagParts" needs to be exported by the entry point index.d.ts +// src/helpers/getBumpedTag.d.ts:33:5 - (ae-forgotten-export) The symbol "AlertError" needs to be exported by the entry point index.d.ts // src/index.d.ts:9:5 - (ae-forgotten-export) The symbol "components" needs to be exported by the entry point index.d.ts // src/index.d.ts:10:5 - (ae-forgotten-export) The symbol "constants" needs to be exported by the entry point index.d.ts // src/index.d.ts:11:5 - (ae-forgotten-export) The symbol "helpers" needs to be exported by the entry point index.d.ts diff --git a/plugins/git-release-manager/package.json b/plugins/git-release-manager/package.json index 27bf139560..a6d91f9844 100644 --- a/plugins/git-release-manager/package.json +++ b/plugins/git-release-manager/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-git-release-manager", "description": "A Backstage plugin that helps you manage releases in git", - "version": "0.3.20-next.3", + "version": "0.3.21", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,10 +24,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/integration": "^1.3.0", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -43,10 +43,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", @@ -55,7 +55,7 @@ "@types/node": "^16.11.26", "@types/recharts": "^1.8.15", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/git-release-manager/src/components/InfoCardPlus.tsx b/plugins/git-release-manager/src/components/InfoCardPlus.tsx index bd0b79ba37..cd682adde1 100644 --- a/plugins/git-release-manager/src/components/InfoCardPlus.tsx +++ b/plugins/git-release-manager/src/components/InfoCardPlus.tsx @@ -17,7 +17,6 @@ import React from 'react'; import { makeStyles } from '@material-ui/core'; import { TEST_IDS } from '../test-helpers/test-ids'; - import { InfoCard } from '@backstage/core-components'; const useStyles = makeStyles(() => ({ @@ -26,7 +25,8 @@ const useStyles = makeStyles(() => ({ }, })); -export const InfoCardPlus = ({ children }: { children?: React.ReactNode }) => { +/** @public */ +export const InfoCardPlus = (props: { children?: React.ReactNode }) => { const classes = useStyles(); return ( @@ -34,7 +34,7 @@ export const InfoCardPlus = ({ children }: { children?: React.ReactNode }) => { style={{ position: 'relative' }} data-testid={TEST_IDS.info.infoFeaturePlus} > - {children} + {props.children} ); }; diff --git a/plugins/git-release-manager/src/helpers/getBumpedTag.ts b/plugins/git-release-manager/src/helpers/getBumpedTag.ts index dbfb00818e..5183947a1c 100644 --- a/plugins/git-release-manager/src/helpers/getBumpedTag.ts +++ b/plugins/git-release-manager/src/helpers/getBumpedTag.ts @@ -28,16 +28,15 @@ import { SemverTagParts } from './tagParts/getSemverTagParts'; * * For semantic versioning this means either a minor or a patch bump * depending on the value of `bumpLevel` + * + * @public */ -export function getBumpedTag({ - project, - tag, - bumpLevel, -}: { +export function getBumpedTag(options: { project: Project; tag: string; bumpLevel: keyof typeof SEMVER_PARTS; }) { + const { project, tag, bumpLevel } = options; const tagParts = getTagParts({ project, tag }); if (tagParts.error !== undefined) { @@ -53,6 +52,7 @@ export function getBumpedTag({ return getBumpedSemverTag(tagParts.tagParts, bumpLevel); } +/** @public */ function getPatchedCalverTag(tagParts: CalverTagParts) { const bumpedTagParts: CalverTagParts = { ...tagParts, @@ -67,6 +67,7 @@ function getPatchedCalverTag(tagParts: CalverTagParts) { }; } +/** @public */ function getBumpedSemverTag( tagParts: SemverTagParts, semverBumpLevel: keyof typeof SEMVER_PARTS, @@ -85,6 +86,8 @@ function getBumpedSemverTag( /** * Calculates the next semantic version, taking into account * whether or not it's a minor or patch + * + * @public */ export function getBumpedSemverTagParts( tagParts: SemverTagParts, diff --git a/plugins/git-release-manager/src/helpers/tagParts/getTagParts.ts b/plugins/git-release-manager/src/helpers/tagParts/getTagParts.ts index 750e4e23c5..ba8412b2b4 100644 --- a/plugins/git-release-manager/src/helpers/tagParts/getTagParts.ts +++ b/plugins/git-release-manager/src/helpers/tagParts/getTagParts.ts @@ -21,17 +21,13 @@ import { Project } from '../../contexts/ProjectContext'; /** * Tag parts are the individual parts of a version, e.g. .. * are the parts of a semantic version + * + * @public */ -export function getTagParts({ - project, - tag, -}: { - project: Project; - tag: string; -}) { - if (project.versioningStrategy === 'calver') { - return getCalverTagParts(tag); +export function getTagParts(options: { project: Project; tag: string }) { + if (options.project.versioningStrategy === 'calver') { + return getCalverTagParts(options.tag); } - return getSemverTagParts(tag); + return getSemverTagParts(options.tag); } diff --git a/plugins/git-release-manager/src/helpers/tagParts/validateTagName.ts b/plugins/git-release-manager/src/helpers/tagParts/validateTagName.ts index b9c0fb74ff..4e35cb0ca4 100644 --- a/plugins/git-release-manager/src/helpers/tagParts/validateTagName.ts +++ b/plugins/git-release-manager/src/helpers/tagParts/validateTagName.ts @@ -18,13 +18,13 @@ import { getCalverTagParts } from './getCalverTagParts'; import { getSemverTagParts } from './getSemverTagParts'; import { Project } from '../../contexts/ProjectContext'; -export const validateTagName = ({ - project, - tagName, -}: { +/** @public */ +export const validateTagName = (options: { project: Project; tagName?: string; }) => { + const { project, tagName } = options; + if (!tagName) { return { tagNameError: null, @@ -33,7 +33,6 @@ export const validateTagName = ({ if (project.versioningStrategy === 'calver') { const { error } = getCalverTagParts(tagName); - return { tagNameError: error, }; diff --git a/plugins/github-actions/CHANGELOG.md b/plugins/github-actions/CHANGELOG.md index 7503f441d6..cb3f73d4cb 100644 --- a/plugins/github-actions/CHANGELOG.md +++ b/plugins/github-actions/CHANGELOG.md @@ -1,5 +1,50 @@ # @backstage/plugin-github-actions +## 0.5.8 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.5.8-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.5.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.5.7 + +### Patch Changes + +- 9de15a41d7: Upgrade @octokit/rest to 19.0.3 +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 217f919f0a: Minor cleanup of the API surface. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.5.7-next.3 ### Patch Changes diff --git a/plugins/github-actions/api-report.md b/plugins/github-actions/api-report.md index 4e5c7f30e9..8cf70eabcc 100644 --- a/plugins/github-actions/api-report.md +++ b/plugins/github-actions/api-report.md @@ -28,35 +28,22 @@ export enum BuildStatus { 'success' = 0, } -// Warning: (ae-missing-release-tag) "EntityGithubActionsContent" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const EntityGithubActionsContent: () => JSX.Element; -// Warning: (ae-missing-release-tag) "EntityLatestGithubActionRunCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityLatestGithubActionRunCard: ({ - branch, - variant, -}: { +export const EntityLatestGithubActionRunCard: (props: { branch: string; variant?: InfoCardVariants | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "EntityLatestGithubActionsForBranchCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntityLatestGithubActionsForBranchCard: ({ - branch, - variant, -}: { +export const EntityLatestGithubActionsForBranchCard: (props: { branch: string; variant?: InfoCardVariants | undefined; }) => JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "EntityRecentGithubActionsRunsCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export const EntityRecentGithubActionsRunsCard: ({ @@ -191,13 +178,12 @@ export class GithubActionsClient implements GithubActionsApi { }): Promise; } -// Warning: (ae-missing-release-tag) "githubActionsPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) const githubActionsPlugin: BackstagePlugin< { entityContent: RouteRef; }, + {}, {} >; export { githubActionsPlugin }; @@ -232,22 +218,21 @@ export type Jobs = { jobs: Job[]; }; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "LatestWorkflowRunCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const LatestWorkflowRunCard: ({ - branch, - variant, -}: Props_2) => JSX.Element; +export const LatestWorkflowRunCard: (props: { + branch: string; + variant?: InfoCardVariants; +}) => JSX.Element; // Warning: (ae-missing-release-tag) "LatestWorkflowsForBranchCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const LatestWorkflowsForBranchCard: ({ - branch, - variant, -}: Props_2) => JSX.Element; +export const LatestWorkflowsForBranchCard: (props: { + branch: string; + variant?: InfoCardVariants; +}) => JSX.Element; // Warning: (ae-missing-release-tag) "RecentWorkflowRunsCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // diff --git a/plugins/github-actions/package.json b/plugins/github-actions/package.json index 3e0b6f5055..634b745f2f 100644 --- a/plugins/github-actions/package.json +++ b/plugins/github-actions/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-actions", "description": "A Backstage plugin that integrates towards GitHub Actions", - "version": "0.5.7-next.3", + "version": "0.5.8", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -36,12 +36,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -55,17 +55,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/github-actions/src/components/Cards/Cards.tsx b/plugins/github-actions/src/components/Cards/Cards.tsx index 61a5146bee..5e53096ba4 100644 --- a/plugins/github-actions/src/components/Cards/Cards.tsx +++ b/plugins/github-actions/src/components/Cards/Cards.tsx @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + import { readGitHubIntegrationConfigs } from '@backstage/integration'; import { useEntity } from '@backstage/plugin-catalog-react'; import { @@ -27,7 +28,6 @@ import { GITHUB_ACTIONS_ANNOTATION } from '../getProjectNameFromEntity'; import { useWorkflowRuns, WorkflowRun } from '../useWorkflowRuns'; import { WorkflowRunsTable } from '../WorkflowRunsTable'; import { WorkflowRunStatus } from '../WorkflowRunStatus'; - import { configApiRef, errorApiRef, useApi } from '@backstage/core-plugin-api'; import { InfoCard, @@ -43,20 +43,18 @@ const useStyles = makeStyles({ }, }); -const WidgetContent = ({ - error, - loading, - lastRun, - branch, -}: { +const WidgetContent = (props: { error?: Error; loading?: boolean; lastRun: WorkflowRun; branch: string; }) => { + const { error, loading, lastRun, branch } = props; const classes = useStyles(); + if (error) return Couldn't fetch latest {branch} run; if (loading) return ; + return ( { +export const LatestWorkflowRunCard = (props: { + branch: string; + variant?: InfoCardVariants; +}) => { + const { branch = 'master', variant } = props; const { entity } = useEntity(); const config = useApi(configApiRef); const errorApi = useApi(errorApiRef); @@ -120,15 +118,11 @@ export const LatestWorkflowRunCard = ({ ); }; -type Props = { +export const LatestWorkflowsForBranchCard = (props: { branch: string; variant?: InfoCardVariants; -}; - -export const LatestWorkflowsForBranchCard = ({ - branch = 'master', - variant, -}: Props) => { +}) => { + const { branch = 'master', variant } = props; const { entity } = useEntity(); return ( diff --git a/plugins/github-actions/src/plugin.ts b/plugins/github-actions/src/plugin.ts index d8db5e16d0..26cf246fb9 100644 --- a/plugins/github-actions/src/plugin.ts +++ b/plugins/github-actions/src/plugin.ts @@ -25,6 +25,7 @@ import { createComponentExtension, } from '@backstage/core-plugin-api'; +/** @public */ export const githubActionsPlugin = createPlugin({ id: 'github-actions', apis: [ @@ -40,6 +41,7 @@ export const githubActionsPlugin = createPlugin({ }, }); +/** @public */ export const EntityGithubActionsContent = githubActionsPlugin.provide( createRoutableExtension({ name: 'EntityGithubActionsContent', @@ -48,6 +50,7 @@ export const EntityGithubActionsContent = githubActionsPlugin.provide( }), ); +/** @public */ export const EntityLatestGithubActionRunCard = githubActionsPlugin.provide( createComponentExtension({ name: 'EntityLatestGithubActionRunCard', @@ -58,6 +61,7 @@ export const EntityLatestGithubActionRunCard = githubActionsPlugin.provide( }), ); +/** @public */ export const EntityLatestGithubActionsForBranchCard = githubActionsPlugin.provide( createComponentExtension({ @@ -71,6 +75,7 @@ export const EntityLatestGithubActionsForBranchCard = }), ); +/** @public */ export const EntityRecentGithubActionsRunsCard = githubActionsPlugin.provide( createComponentExtension({ name: 'EntityRecentGithubActionsRunsCard', diff --git a/plugins/github-deployments/CHANGELOG.md b/plugins/github-deployments/CHANGELOG.md index 35503a6a64..0e331108a3 100644 --- a/plugins/github-deployments/CHANGELOG.md +++ b/plugins/github-deployments/CHANGELOG.md @@ -1,5 +1,54 @@ # @backstage/plugin-github-deployments +## 0.1.39 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/integration-react@1.1.3 + +## 0.1.39-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + +## 0.1.39-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.38 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 0f25116d28: Updated dependency `@octokit/graphql` to `^5.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.1.38-next.3 ### Patch Changes diff --git a/plugins/github-deployments/api-report.md b/plugins/github-deployments/api-report.md index 36680cb020..3e75b2f9bc 100644 --- a/plugins/github-deployments/api-report.md +++ b/plugins/github-deployments/api-report.md @@ -47,7 +47,7 @@ export const EntityGithubDeploymentsCard: (props: { // Warning: (ae-missing-release-tag) "githubDeploymentsPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const githubDeploymentsPlugin: BackstagePlugin<{}, {}>; +export const githubDeploymentsPlugin: BackstagePlugin<{}, {}, {}>; // Warning: (ae-forgotten-export) The symbol "GithubDeploymentsTableProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "GithubDeploymentsTable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) diff --git a/plugins/github-deployments/package.json b/plugins/github-deployments/package.json index 1829974873..bacd3d9574 100644 --- a/plugins/github-deployments/package.json +++ b/plugins/github-deployments/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-github-deployments", "description": "A Backstage plugin that integrates towards GitHub Deployments", - "version": "0.1.38-next.3", + "version": "0.1.39", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,14 +24,14 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/integration-react": "^1.1.2-next.3", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/integration-react": "^1.1.3", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -43,17 +43,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/github-issues/.eslintrc.js b/plugins/github-issues/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/github-issues/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/github-issues/CHANGELOG.md b/plugins/github-issues/CHANGELOG.md new file mode 100644 index 0000000000..a85982820d --- /dev/null +++ b/plugins/github-issues/CHANGELOG.md @@ -0,0 +1,31 @@ +# @backstage/plugin-github-issues + +## 0.1.0 + +### Minor Changes + +- ffd5e47fb5: New plugin for displaying GitHub Issues added + +### Patch Changes + +- 347ea327c2: Moved communication with GitHub graphql API to the dedicated plugin API. + Fixes issue when no GitHub Issues are rendered when partial failure is returned from GitHub API. +- b522f49403: Updated dependency `@spotify/prettier-config` to `^14.0.0`. +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.1.0-next.0 + +### Minor Changes + +- ffd5e47fb5: New plugin for displaying GitHub Issues added + +### Patch Changes + +- b522f49403: Updated dependency `@spotify/prettier-config` to `^14.0.0`. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 diff --git a/plugins/github-issues/README.md b/plugins/github-issues/README.md new file mode 100644 index 0000000000..eeb93ab27b --- /dev/null +++ b/plugins/github-issues/README.md @@ -0,0 +1,63 @@ +# GitHub Issues plugin + +Welcome to the GitHub Issues plugin! + +Based on the [well-known GitHub slug annotation](https://backstage.io/docs/features/software-catalog/well-known-annotations#githubcomproject-slug) associated with the Entity, it renders the list of Open issues in GitHub. + +The plugin is designed to work with four Entity kinds, and it behaves a bit differently depending on that kind: + +- Kind: Group/User: plugin renders issues from all repositories for which the Entity is the owner. +- Kind: API/Component: plugin renders issues from only one repository assigned to the Entity + +**Issues are sorted from the recently updated DESC order (the plugin might not render all issues from a single repo next to each other).** + +## Prerequisites + +- [GitHub Authentication Provider](https://backstage.io/docs/auth/github/provider) + +## Usage + +Install the plugin by running the following command **from your Backstage root directory** + +`yarn --cwd packages/app add @backstage/plugin-github-issues` + +After installation, the plugin can be used as a Card or as a Page. + +```typescript +import { + GitHubIssuesCard, + GitHubIssuesPage, +} from '@backstage/plugin-github-issues'; + +// To use as a page Plugin needs to be wrapped in EntityLayout.Route +const RenderGitHubIssuesPage = () => ( + + + + + + + +); + +// To use as a card and make it render correctly please place it inside appropriate Grid elements +const RenderGitHubIssuesCard = () => ( + + + + + + + + + +); +``` + +## Configuration + +Both `GitHubIssuesPage` and `GitHubIssuesCard` provide default configuration. It is ready to use out of the box. +However, you can configure the plugin with props: + +- `itemsPerPage: number = 10` - Issues in the list are paginated, number of issues on a single page is controlled with this prop +- `itemsPerRepo: number = 40` - the plugin doesn't download all Issues available on GitHub. By default, it will get at most 40 Issues - this prop controls this behaviour diff --git a/plugins/github-issues/api-report.md b/plugins/github-issues/api-report.md new file mode 100644 index 0000000000..eb69fc8e8e --- /dev/null +++ b/plugins/github-issues/api-report.md @@ -0,0 +1,33 @@ +## API Report File for "@backstage/plugin-github-issues" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +/// + +import { BackstagePlugin } from '@backstage/core-plugin-api'; +import { RouteRef } from '@backstage/core-plugin-api'; + +// @public (undocumented) +export const GitHubIssuesCard: (props: GitHubIssuesProps) => JSX.Element; + +// @public (undocumented) +export const GitHubIssuesPage: (props: GitHubIssuesProps) => JSX.Element; + +// @public (undocumented) +export const gitHubIssuesPlugin: BackstagePlugin< + { + root: RouteRef; + }, + {}, + {} +>; + +// @public (undocumented) +export type GitHubIssuesProps = { + itemsPerPage?: number; + itemsPerRepo?: number; +}; + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/github-issues/dev/__fixtures__/component-issues-data.json b/plugins/github-issues/dev/__fixtures__/component-issues-data.json new file mode 100644 index 0000000000..8192f38838 --- /dev/null +++ b/plugins/github-issues/dev/__fixtures__/component-issues-data.json @@ -0,0 +1,1209 @@ +{ + "backstage": { + "issues": { + "totalCount": 464, + "edges": [ + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1112.jpg", + "login": "worthless-horse" + } + } + ] + }, + "author": { + "login": "next-dog" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "quasi labore qui", + "url": "http://flowery-muscatel.net", + "participants": { + "totalCount": 3 + }, + "updatedAt": "2022-05-02T09:46:35.885Z", + "createdAt": "2022-06-03T07:11:22.320Z", + "comments": { + "totalCount": 6 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1061.jpg", + "login": "colorful-bird" + } + } + ] + }, + "author": { + "login": "loud-cow" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "debitis alias voluptatem", + "url": "https://complete-grief.biz", + "participants": { + "totalCount": 5 + }, + "updatedAt": "2022-05-04T19:44:01.090Z", + "createdAt": "2022-02-21T08:07:57.434Z", + "comments": { + "totalCount": 1 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1222.jpg", + "login": "sharp-cetacean" + } + } + ] + }, + "author": { + "login": "growing-dog" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "non accusamus occaecati", + "url": "http://medium-choosing.com", + "participants": { + "totalCount": 3 + }, + "updatedAt": "2021-10-28T00:36:58.871Z", + "createdAt": "2021-11-08T02:21:55.269Z", + "comments": { + "totalCount": 2 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/513.jpg", + "login": "crafty-crocodilia" + } + } + ] + }, + "author": { + "login": "wooden-crocodilia" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "tenetur distinctio sint", + "url": "http://opulent-prejudice.biz", + "participants": { + "totalCount": 5 + }, + "updatedAt": "2022-08-10T19:22:08.823Z", + "createdAt": "2022-02-21T06:24:45.090Z", + "comments": { + "totalCount": 7 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/785.jpg", + "login": "genuine-cow" + } + } + ] + }, + "author": { + "login": "likely-snake" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "eveniet sed nesciunt", + "url": "http://flickering-atmosphere.com", + "participants": { + "totalCount": 5 + }, + "updatedAt": "2022-02-26T15:54:42.831Z", + "createdAt": "2022-02-13T14:52:35.327Z", + "comments": { + "totalCount": 2 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/503.jpg", + "login": "imaginary-lion" + } + } + ] + }, + "author": { + "login": "lame-bird" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "saepe sequi dolore", + "url": "https://short-term-broccoli.org", + "participants": { + "totalCount": 2 + }, + "updatedAt": "2021-10-11T01:31:28.508Z", + "createdAt": "2022-04-11T12:41:01.234Z", + "comments": { + "totalCount": 3 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/590.jpg", + "login": "funny-snake" + } + } + ] + }, + "author": { + "login": "hollow-snake" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "enim quia magni", + "url": "https://scornful-servant.name", + "participants": { + "totalCount": 5 + }, + "updatedAt": "2022-03-05T19:19:15.147Z", + "createdAt": "2022-03-13T09:25:35.802Z", + "comments": { + "totalCount": 8 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/588.jpg", + "login": "zigzag-bear" + } + } + ] + }, + "author": { + "login": "growling-cow" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "omnis ut nostrum", + "url": "https://worthy-minority.net", + "participants": { + "totalCount": 7 + }, + "updatedAt": "2021-08-18T19:21:40.603Z", + "createdAt": "2022-06-04T16:06:26.277Z", + "comments": { + "totalCount": 4 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1134.jpg", + "login": "composed-lion" + } + } + ] + }, + "author": { + "login": "overjoyed-crocodilia" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "sit est corrupti", + "url": "http://vital-armpit.com", + "participants": { + "totalCount": 3 + }, + "updatedAt": "2022-07-26T22:13:34.123Z", + "createdAt": "2022-02-28T17:59:42.677Z", + "comments": { + "totalCount": 3 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/802.jpg", + "login": "sarcastic-bear" + } + } + ] + }, + "author": { + "login": "utilized-insect" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "illo perferendis suscipit", + "url": "http://snappy-skywalk.info", + "participants": { + "totalCount": 4 + }, + "updatedAt": "2021-10-02T21:22:35.070Z", + "createdAt": "2021-10-25T11:36:35.561Z", + "comments": { + "totalCount": 2 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/232.jpg", + "login": "pristine-cow" + } + } + ] + }, + "author": { + "login": "adorable-snake" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "assumenda nostrum aut", + "url": "http://loud-legend.info", + "participants": { + "totalCount": 7 + }, + "updatedAt": "2022-06-16T22:45:23.107Z", + "createdAt": "2022-05-23T01:10:35.755Z", + "comments": { + "totalCount": 1 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/652.jpg", + "login": "wrong-insect" + } + } + ] + }, + "author": { + "login": "grizzled-cow" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "qui magnam dolorem", + "url": "http://exhausted-horn.org", + "participants": { + "totalCount": 7 + }, + "updatedAt": "2021-12-18T18:46:10.828Z", + "createdAt": "2022-03-27T06:42:04.192Z", + "comments": { + "totalCount": 7 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/838.jpg", + "login": "humming-cow" + } + } + ] + }, + "author": { + "login": "profuse-bird" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "nostrum numquam porro", + "url": "https://unusual-reaction.org", + "participants": { + "totalCount": 7 + }, + "updatedAt": "2022-05-11T15:14:57.433Z", + "createdAt": "2022-05-06T10:48:16.946Z", + "comments": { + "totalCount": 8 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/573.jpg", + "login": "prime-cow" + } + } + ] + }, + "author": { + "login": "forthright-lion" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "in inventore pariatur", + "url": "https://cheery-accord.info", + "participants": { + "totalCount": 4 + }, + "updatedAt": "2022-06-30T16:22:46.819Z", + "createdAt": "2022-05-11T12:37:36.848Z", + "comments": { + "totalCount": 6 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1143.jpg", + "login": "limp-bear" + } + } + ] + }, + "author": { + "login": "faraway-rabbit" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "et dolores eaque", + "url": "http://overjoyed-former.info", + "participants": { + "totalCount": 4 + }, + "updatedAt": "2022-04-19T15:14:58.698Z", + "createdAt": "2022-04-28T23:15:49.918Z", + "comments": { + "totalCount": 1 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/347.jpg", + "login": "same-insect" + } + } + ] + }, + "author": { + "login": "smoggy-bird" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "vel error numquam", + "url": "http://submissive-ladder.org", + "participants": { + "totalCount": 3 + }, + "updatedAt": "2021-12-19T23:43:44.987Z", + "createdAt": "2022-01-04T11:52:01.233Z", + "comments": { + "totalCount": 4 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/951.jpg", + "login": "round-dog" + } + } + ] + }, + "author": { + "login": "humming-cetacean" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "doloribus asperiores occaecati", + "url": "http://webbed-underclothes.biz", + "participants": { + "totalCount": 2 + }, + "updatedAt": "2022-04-19T07:07:21.270Z", + "createdAt": "2022-04-20T10:41:00.681Z", + "comments": { + "totalCount": 2 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1123.jpg", + "login": "tepid-cat" + } + } + ] + }, + "author": { + "login": "colossal-bird" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "reiciendis illum quos", + "url": "http://rusty-repeat.com", + "participants": { + "totalCount": 7 + }, + "updatedAt": "2022-08-04T06:35:11.880Z", + "createdAt": "2022-07-16T15:11:56.116Z", + "comments": { + "totalCount": 7 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1068.jpg", + "login": "grown-cat" + } + } + ] + }, + "author": { + "login": "superficial-lion" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "tempore et sequi", + "url": "https://defenseless-signal.info", + "participants": { + "totalCount": 2 + }, + "updatedAt": "2022-03-12T10:17:20.598Z", + "createdAt": "2022-05-31T20:12:43.316Z", + "comments": { + "totalCount": 7 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/468.jpg", + "login": "blissful-horse" + } + } + ] + }, + "author": { + "login": "positive-insect" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "aut minima odit", + "url": "https://well-groomed-octave.biz", + "participants": { + "totalCount": 4 + }, + "updatedAt": "2021-08-20T21:00:05.294Z", + "createdAt": "2022-04-11T23:51:45.727Z", + "comments": { + "totalCount": 9 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1044.jpg", + "login": "crowded-bird" + } + } + ] + }, + "author": { + "login": "unlined-horse" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "aut sunt quisquam", + "url": "https://realistic-student.com", + "participants": { + "totalCount": 5 + }, + "updatedAt": "2021-11-07T11:13:39.158Z", + "createdAt": "2022-01-30T19:35:35.546Z", + "comments": { + "totalCount": 2 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/691.jpg", + "login": "loathsome-insect" + } + } + ] + }, + "author": { + "login": "kooky-crocodilia" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "reprehenderit non eos", + "url": "https://alert-testimony.net", + "participants": { + "totalCount": 3 + }, + "updatedAt": "2022-04-24T16:34:36.616Z", + "createdAt": "2021-11-01T21:35:35.900Z", + "comments": { + "totalCount": 5 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/691.jpg", + "login": "dear-insect" + } + } + ] + }, + "author": { + "login": "wavy-bear" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "quis in earum", + "url": "https://radiant-posterior.net", + "participants": { + "totalCount": 7 + }, + "updatedAt": "2021-09-26T08:50:55.755Z", + "createdAt": "2022-04-10T00:03:40.290Z", + "comments": { + "totalCount": 8 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/952.jpg", + "login": "prestigious-cat" + } + } + ] + }, + "author": { + "login": "quick-cetacean" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "sed ut exercitationem", + "url": "https://portly-clasp.name", + "participants": { + "totalCount": 3 + }, + "updatedAt": "2022-04-06T03:04:16.077Z", + "createdAt": "2022-01-14T10:22:19.619Z", + "comments": { + "totalCount": 5 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/768.jpg", + "login": "fatal-cetacean" + } + } + ] + }, + "author": { + "login": "pricey-dog" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "voluptas error sunt", + "url": "http://second-outcome.info", + "participants": { + "totalCount": 5 + }, + "updatedAt": "2021-08-19T20:35:40.281Z", + "createdAt": "2021-10-02T12:24:16.983Z", + "comments": { + "totalCount": 6 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/283.jpg", + "login": "double-fish" + } + } + ] + }, + "author": { + "login": "liquid-snake" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "sed reprehenderit sunt", + "url": "https://playful-fibrosis.com", + "participants": { + "totalCount": 7 + }, + "updatedAt": "2022-05-24T19:35:19.804Z", + "createdAt": "2022-04-04T20:15:10.303Z", + "comments": { + "totalCount": 3 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/38.jpg", + "login": "separate-cat" + } + } + ] + }, + "author": { + "login": "jolly-bear" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "accusantium cupiditate et", + "url": "http://lined-flood.biz", + "participants": { + "totalCount": 9 + }, + "updatedAt": "2022-01-23T15:45:04.503Z", + "createdAt": "2021-11-29T07:20:44.372Z", + "comments": { + "totalCount": 4 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/410.jpg", + "login": "yummy-dog" + } + } + ] + }, + "author": { + "login": "pesky-bear" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "eum molestiae accusantium", + "url": "http://vast-grub.biz", + "participants": { + "totalCount": 7 + }, + "updatedAt": "2022-05-24T12:02:33.225Z", + "createdAt": "2022-02-26T14:40:38.285Z", + "comments": { + "totalCount": 5 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/186.jpg", + "login": "unique-cow" + } + } + ] + }, + "author": { + "login": "remorseful-horse" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "ea eligendi dolore", + "url": "http://mammoth-wick.biz", + "participants": { + "totalCount": 7 + }, + "updatedAt": "2022-07-02T12:23:03.701Z", + "createdAt": "2022-06-30T03:56:08.273Z", + "comments": { + "totalCount": 4 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/605.jpg", + "login": "soft-insect" + } + } + ] + }, + "author": { + "login": "vengeful-fish" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "eum in esse", + "url": "https://immaculate-liability.info", + "participants": { + "totalCount": 4 + }, + "updatedAt": "2022-06-14T02:40:34.008Z", + "createdAt": "2022-04-07T14:46:48.442Z", + "comments": { + "totalCount": 2 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/916.jpg", + "login": "wretched-cow" + } + } + ] + }, + "author": { + "login": "popular-insect" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "est voluptatem molestiae", + "url": "http://venerated-chocolate.biz", + "participants": { + "totalCount": 1 + }, + "updatedAt": "2021-10-08T18:02:11.052Z", + "createdAt": "2021-09-28T09:48:13.138Z", + "comments": { + "totalCount": 1 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/218.jpg", + "login": "flawless-dog" + } + } + ] + }, + "author": { + "login": "made-up-lion" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "sunt atque corrupti", + "url": "https://secondary-flight.biz", + "participants": { + "totalCount": 7 + }, + "updatedAt": "2021-12-31T07:36:01.831Z", + "createdAt": "2022-03-29T20:52:30.083Z", + "comments": { + "totalCount": 6 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1099.jpg", + "login": "nervous-dog" + } + } + ] + }, + "author": { + "login": "inconsequential-cat" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "vel quo nam", + "url": "https://third-week.info", + "participants": { + "totalCount": 5 + }, + "updatedAt": "2022-03-06T07:42:44.049Z", + "createdAt": "2021-08-16T14:34:09.635Z", + "comments": { + "totalCount": 8 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/688.jpg", + "login": "dark-dog" + } + } + ] + }, + "author": { + "login": "modest-rabbit" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "rerum non nam", + "url": "http://complete-registry.net", + "participants": { + "totalCount": 5 + }, + "updatedAt": "2022-05-04T02:09:20.355Z", + "createdAt": "2022-06-08T12:23:09.380Z", + "comments": { + "totalCount": 1 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/489.jpg", + "login": "blond-insect" + } + } + ] + }, + "author": { + "login": "terrible-snake" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "accusamus quis non", + "url": "https://rosy-childhood.com", + "participants": { + "totalCount": 6 + }, + "updatedAt": "2021-12-14T12:46:15.628Z", + "createdAt": "2022-02-19T00:45:57.573Z", + "comments": { + "totalCount": 8 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1094.jpg", + "login": "creative-bird" + } + } + ] + }, + "author": { + "login": "grotesque-dog" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "consectetur id et", + "url": "http://some-innocent.info", + "participants": { + "totalCount": 8 + }, + "updatedAt": "2021-11-27T11:12:58.067Z", + "createdAt": "2021-12-10T00:15:14.640Z", + "comments": { + "totalCount": 8 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/583.jpg", + "login": "drab-horse" + } + } + ] + }, + "author": { + "login": "acceptable-snake" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "ipsum beatae voluptas", + "url": "https://faithful-down.info", + "participants": { + "totalCount": 6 + }, + "updatedAt": "2022-08-13T17:03:33.381Z", + "createdAt": "2021-10-05T11:26:39.392Z", + "comments": { + "totalCount": 8 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/578.jpg", + "login": "esteemed-bird" + } + } + ] + }, + "author": { + "login": "cultured-fish" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "odio perferendis maxime", + "url": "https://minty-tactics.info", + "participants": { + "totalCount": 2 + }, + "updatedAt": "2022-01-25T02:14:59.148Z", + "createdAt": "2021-09-23T04:02:15.225Z", + "comments": { + "totalCount": 4 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/917.jpg", + "login": "quiet-bear" + } + } + ] + }, + "author": { + "login": "ill-fated-lion" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "sed enim laudantium", + "url": "https://welcome-provider.org", + "participants": { + "totalCount": 6 + }, + "updatedAt": "2022-02-24T23:08:19.320Z", + "createdAt": "2021-09-13T03:10:39.303Z", + "comments": { + "totalCount": 2 + } + } + }, + { + "node": { + "assignees": { + "edges": [ + { + "node": { + "avatarUrl": "https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/973.jpg", + "login": "portly-crocodilia" + } + } + ] + }, + "author": { + "login": "antique-bird" + }, + "repository": { + "nameWithOwner": "backstage/backstage" + }, + "title": "enim accusamus consequuntur", + "url": "http://shady-impudence.net", + "participants": { + "totalCount": 2 + }, + "updatedAt": "2021-12-04T05:35:50.780Z", + "createdAt": "2021-12-21T11:44:33.940Z", + "comments": { + "totalCount": 9 + } + } + } + ] + } + } +} diff --git a/plugins/github-issues/dev/index.tsx b/plugins/github-issues/dev/index.tsx new file mode 100644 index 0000000000..a5f20ab9b9 --- /dev/null +++ b/plugins/github-issues/dev/index.tsx @@ -0,0 +1,66 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { createDevApp } from '@backstage/dev-utils'; +import { + CatalogApi, + catalogApiRef, + EntityProvider, +} from '@backstage/plugin-catalog-react'; + +import { gitHubIssuesPlugin, GitHubIssuesPage } from '../src'; +import { GitHubIssuesApi, gitHubIssuesApiRef } from '../src/api'; + +import testData from './__fixtures__/component-issues-data.json'; + +createDevApp() + .registerPlugin(gitHubIssuesPlugin) + .registerApi({ + api: gitHubIssuesApiRef, + deps: {}, + factory: () => + ({ + fetchIssuesByRepoFromGitHub: async () => testData, + } as GitHubIssuesApi), + }) + .registerApi({ + api: catalogApiRef, + deps: {}, + factory: () => + ({ + getEntities: () => ({}), + } as CatalogApi), + }) + .addPage({ + title: 'Component Issues', + element: ( + + + + ), + }) + .render(); diff --git a/plugins/github-issues/package.json b/plugins/github-issues/package.json new file mode 100644 index 0000000000..712f0d81c9 --- /dev/null +++ b/plugins/github-issues/package.json @@ -0,0 +1,60 @@ +{ + "name": "@backstage/plugin-github-issues", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "publishConfig": { + "access": "public", + "main": "dist/index.esm.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "frontend-plugin" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/catalog-model": "^1.0.3", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.15", + "@material-ui/core": "^4.12.4", + "@material-ui/icons": "^4.9.1", + "@material-ui/lab": "^4.0.0-alpha.61", + "luxon": "^2.4.0", + "octokit": "^2.0.4", + "react-use": "^17.4.0" + }, + "peerDependencies": { + "react": "^16.13.1 || ^17.0.0" + }, + "devDependencies": { + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", + "@spotify/prettier-config": "^14.0.0", + "@testing-library/jest-dom": "^5.10.1", + "@testing-library/react": "^12.1.3", + "@testing-library/user-event": "^14.0.0", + "@types/jest": "*", + "@types/node": "*", + "@types/react": "^16.13.1 || ^17.0.0", + "cross-fetch": "^3.1.5", + "msw": "^0.45.0" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/github-issues/src/api/gitHubIssuesApi.test.ts b/plugins/github-issues/src/api/gitHubIssuesApi.test.ts new file mode 100644 index 0000000000..4d1c3ffff3 --- /dev/null +++ b/plugins/github-issues/src/api/gitHubIssuesApi.test.ts @@ -0,0 +1,300 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +const mockGraphQLQuery = jest.fn(() => ({})); +jest.mock('octokit', () => ({ + Octokit: jest.fn(() => ({ graphql: mockGraphQLQuery })), +})); + +import { ConfigApi, ErrorApi } from '@backstage/core-plugin-api'; +import { ForwardedError } from '@backstage/errors'; +import { gitHubIssuesApi } from './gitHubIssuesApi'; + +describe('gitHubIssuesApi', () => { + describe('fetchIssuesByRepoFromGitHub', () => { + it('should call GitHub API with correct query with fragment for each repo', async () => { + const api = gitHubIssuesApi( + { getAccessToken: jest.fn() }, + { + getOptionalConfigArray: jest.fn(), + } as unknown as ConfigApi, + { post: jest.fn() } as unknown as ErrorApi, + ); + + await api.fetchIssuesByRepoFromGitHub( + ['mrwolny/yo-yo', 'mrwolny/yoyo', 'mrwolny/yo.yo'], + 10, + ); + expect(mockGraphQLQuery).toHaveBeenCalledTimes(1); + expect(mockGraphQLQuery).toHaveBeenCalledWith( + '\n' + + ' \n' + + ' fragment issues on Repository {\n' + + ' issues(\n' + + ' states: OPEN\n' + + ' first: 10\n' + + ' orderBy: { field: UPDATED_AT, direction: DESC }\n' + + ' ) {\n' + + ' totalCount\n' + + ' edges {\n' + + ' node {\n' + + ' assignees(first: 10) {\n' + + ' edges {\n' + + ' node {\n' + + ' avatarUrl\n' + + ' login\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' author {\n' + + ' login\n' + + ' }\n' + + ' repository {\n' + + ' nameWithOwner\n' + + ' }\n' + + ' title\n' + + ' url\n' + + ' participants {\n' + + ' totalCount\n' + + ' }\n' + + ' updatedAt\n' + + ' createdAt\n' + + ' comments(last: 1) {\n' + + ' totalCount\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' }\n' + + ' \n' + + '\n' + + ' query {\n' + + ' \n' + + ' yoyo: repository(name: "yo-yo", owner: "mrwolny") {\n' + + ' ...issues\n' + + ' }\n' + + ' ,\n' + + ' yoyox: repository(name: "yoyo", owner: "mrwolny") {\n' + + ' ...issues\n' + + ' }\n' + + ' ,\n' + + ' yoyoxx: repository(name: "yo.yo", owner: "mrwolny") {\n' + + ' ...issues\n' + + ' }\n' + + ' \n' + + ' } \n' + + ' ', + ); + }); + }); + + it('should return data for repos with successfully retrieved issues when GitHub returns partial failure', async () => { + mockGraphQLQuery.mockImplementationOnce(() => + Promise.reject({ + data: { + yoyo: { + issues: { + totalCount: 1, + edges: [ + { + node: { + assignees: { + edges: [], + }, + author: { + login: 'mrwolny', + }, + repository: { + nameWithOwner: 'mrwolny/yo-yo', + }, + title: "It's the ISSUE!", + url: 'https://github.com/mrwolny/yo-yo/issues/1', + participants: { + totalCount: 1, + }, + updatedAt: '2022-07-04T18:47:33Z', + createdAt: '2022-06-23T18:14:26Z', + comments: { + totalCount: 4, + }, + }, + }, + ], + }, + }, + notfound: null, + }, + errors: [ + { + type: 'NOT_FOUND', + path: ['notfound'], + locations: [ + { + line: 48, + column: 9, + }, + ], + message: + "Could not resolve to a Repository with the name 'notfound/notfound'.", + }, + ], + }), + ); + + const api = gitHubIssuesApi( + { getAccessToken: jest.fn() }, + { + getOptionalConfigArray: jest.fn(), + } as unknown as ConfigApi, + { post: jest.fn() } as unknown as ErrorApi, + ); + + const data = await api.fetchIssuesByRepoFromGitHub( + ['mrwolny/yo-yo', 'mrwolny/notfound'], + 10, + ); + + expect(data).toEqual({ + 'mrwolny/yo-yo': { + issues: { + totalCount: 1, + edges: [ + { + node: { + assignees: { + edges: [], + }, + author: { + login: 'mrwolny', + }, + repository: { + nameWithOwner: 'mrwolny/yo-yo', + }, + title: "It's the ISSUE!", + url: 'https://github.com/mrwolny/yo-yo/issues/1', + participants: { + totalCount: 1, + }, + updatedAt: '2022-07-04T18:47:33Z', + createdAt: '2022-06-23T18:14:26Z', + comments: { + totalCount: 4, + }, + }, + }, + ], + }, + }, + }); + }); + + it('should return empty object when GitHub returns failure with no data', async () => { + mockGraphQLQuery.mockImplementationOnce(() => + Promise.reject({ + data: { + notfound: null, + }, + errors: [ + { + type: 'NOT_FOUND', + path: ['notfound'], + locations: [ + { + line: 48, + column: 9, + }, + ], + message: + "Could not resolve to a Repository with the name 'notfound/notfound'.", + }, + ], + }), + ); + + const api = gitHubIssuesApi( + { getAccessToken: jest.fn() }, + { + getOptionalConfigArray: jest.fn(), + } as unknown as ConfigApi, + { post: jest.fn() } as unknown as ErrorApi, + ); + + const data = await api.fetchIssuesByRepoFromGitHub( + ['mrwolny/notfound'], + 10, + ); + + expect(data).toEqual({}); + }); + + it('should post error to the backstage error API when GitHub returns failure', async () => { + mockGraphQLQuery.mockImplementationOnce(() => + Promise.reject({ + data: { + notfound: null, + }, + errors: [ + { + type: 'NOT_FOUND', + path: ['notfound'], + locations: [ + { + line: 48, + column: 9, + }, + ], + message: + "Could not resolve to a Repository with the name 'notfound/notfound'.", + }, + ], + }), + ); + + const mockErrorApi = { post: jest.fn() }; + + const api = gitHubIssuesApi( + { getAccessToken: jest.fn() }, + { + getOptionalConfigArray: jest.fn(), + } as unknown as ConfigApi, + mockErrorApi as unknown as ErrorApi, + ); + + await api.fetchIssuesByRepoFromGitHub(['mrwolny/notfound'], 10); + + expect(mockErrorApi.post).toHaveBeenCalledTimes(1); + expect(mockErrorApi.post).toHaveBeenCalledWith( + new ForwardedError('GitHub Issues Plugin failure', { + data: { + notfound: null, + }, + errors: [ + { + type: 'NOT_FOUND', + path: ['notfound'], + locations: [ + { + line: 48, + column: 9, + }, + ], + message: + "Could not resolve to a Repository with the name 'notfound/notfound'.", + }, + ], + }), + ); + }); +}); diff --git a/plugins/github-issues/src/api/gitHubIssuesApi.ts b/plugins/github-issues/src/api/gitHubIssuesApi.ts new file mode 100644 index 0000000000..816345940c --- /dev/null +++ b/plugins/github-issues/src/api/gitHubIssuesApi.ts @@ -0,0 +1,217 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Octokit } from 'octokit'; +import { + createApiRef, + ConfigApi, + ErrorApi, + OAuthApi, +} from '@backstage/core-plugin-api'; +import { readGitHubIntegrationConfigs } from '@backstage/integration'; +import { ForwardedError } from '@backstage/errors'; + +/** @internal */ +export type Assignee = { + avatarUrl: string; + login: string; +}; + +/** @internal */ +export type EdgesWithNodes = { + edges: Array<{ + node: T; + }>; +}; + +/** @internal */ +export type IssueAuthor = { + login: string; +}; + +/** @internal */ +export type Issue = { + assignees: EdgesWithNodes; + author: IssueAuthor; + repository: { + nameWithOwner: string; + }; + title: string; + url: string; + participants: { + totalCount: number; + }; + createdAt: string; + updatedAt: string; + comments: { + totalCount: number; + }; +}; + +/** @internal */ +export type RepoIssues = { + issues: { + totalCount: number; + } & EdgesWithNodes; +}; + +/** @internal */ +export type IssuesByRepo = Record; + +/** @internal */ +export type GitHubIssuesApi = ReturnType; + +/** @internal */ +export const gitHubIssuesApiRef = createApiRef({ + id: 'plugin.githubissues.service', +}); + +/** @internal */ +export const gitHubIssuesApi = ( + githubAuthApi: OAuthApi, + configApi: ConfigApi, + errorApi: ErrorApi, +) => { + let octokit: Octokit; + + const getOctokit = async () => { + const baseUrl = readGitHubIntegrationConfigs( + configApi.getOptionalConfigArray('integrations.github') ?? [], + )[0].apiBaseUrl; + + const token = await githubAuthApi.getAccessToken(['repo']); + + if (!octokit) { + octokit = new Octokit({ auth: token, ...(baseUrl && { baseUrl }) }); + } + + return octokit.graphql; + }; + + const fetchIssuesByRepoFromGitHub = async ( + repos: Array, + itemsPerRepo: number, + ): Promise => { + const graphql = await getOctokit(); + const safeNames: Array = []; + + const repositories = repos.map(repo => { + const [owner, name] = repo.split('/'); + + const safeNameRegex = /-|\./gi; + let safeName = name.replace(safeNameRegex, ''); + + while (safeNames.includes(safeName)) { + safeName += 'x'; + } + + safeNames.push(safeName); + + return { + safeName, + name, + owner, + }; + }); + + let issuesByRepo: IssuesByRepo = {}; + try { + issuesByRepo = await graphql( + createIssueByRepoQuery(repositories, itemsPerRepo), + ); + } catch (e) { + if (e.data) { + issuesByRepo = e.data; + } + + errorApi.post(new ForwardedError('GitHub Issues Plugin failure', e)); + } + + return repositories.reduce((acc, { safeName, name, owner }) => { + if (issuesByRepo[safeName]) { + acc[`${owner}/${name}`] = issuesByRepo[safeName]; + } + + return acc; + }, {} as IssuesByRepo); + }; + + return { fetchIssuesByRepoFromGitHub }; +}; + +function createIssueByRepoQuery( + repositories: Array<{ + safeName: string; + name: string; + owner: string; + }>, + itemsPerRepo: number, +): string { + const fragment = ` + fragment issues on Repository { + issues( + states: OPEN + first: ${itemsPerRepo} + orderBy: { field: UPDATED_AT, direction: DESC } + ) { + totalCount + edges { + node { + assignees(first: 10) { + edges { + node { + avatarUrl + login + } + } + } + author { + login + } + repository { + nameWithOwner + } + title + url + participants { + totalCount + } + updatedAt + createdAt + comments(last: 1) { + totalCount + } + } + } + } + } + `; + + const query = ` + ${fragment} + + query { + ${repositories.map( + ({ safeName, name, owner }) => ` + ${safeName}: repository(name: "${name}", owner: "${owner}") { + ...issues + } + `, + )} + } + `; + + return query; +} diff --git a/plugins/github-issues/src/api/index.ts b/plugins/github-issues/src/api/index.ts new file mode 100644 index 0000000000..4cc3372c45 --- /dev/null +++ b/plugins/github-issues/src/api/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export * from './gitHubIssuesApi'; diff --git a/plugins/github-issues/src/components/GitHubIssues/GitHubIssues.test.tsx b/plugins/github-issues/src/components/GitHubIssues/GitHubIssues.test.tsx new file mode 100644 index 0000000000..33eec79359 --- /dev/null +++ b/plugins/github-issues/src/components/GitHubIssues/GitHubIssues.test.tsx @@ -0,0 +1,161 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { renderInTestApp, TestApiProvider } from '@backstage/test-utils'; +import { + EntityProvider, + catalogApiRef, + CatalogApi, +} from '@backstage/plugin-catalog-react'; +import { Entity } from '@backstage/catalog-model'; + +import { GitHubIssuesApi, gitHubIssuesApiRef, Issue } from '../../api'; + +import { GitHubIssues } from './GitHubIssues'; + +const getTestIssue = (overwrites: Partial = {}): { node: Issue } => ({ + node: { + ...{ + assignees: { + edges: [ + { + node: { + avatarUrl: + 'https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1112.jpg', + login: 'worthless-horse', + }, + }, + ], + }, + author: { + login: 'next-dog', + }, + repository: { + nameWithOwner: 'backstage/backstage', + }, + title: 'quasi labore qui', + url: 'http://flowery-muscatel.net', + participants: { + totalCount: 3, + }, + updatedAt: '2022-05-02T09:46:35.885Z', + createdAt: '2022-06-03T07:11:22.320Z', + comments: { + totalCount: 6, + }, + }, + ...overwrites, + }, +}); + +jest + .useFakeTimers() + .setSystemTime(new Date('2020-04-20T08:15:47.614Z').getTime()); + +const entityComponent = { + metadata: { + annotations: { + 'github.com/project-slug': 'backstage/backstage', + }, + name: 'backstage', + }, + apiVersion: 'backstage.io/v1alpha1', + kind: 'Component', +} as unknown as Entity; + +const mockCatalogApi = { + getEntities: () => ({}), +} as CatalogApi; + +describe('GitHubIssues', () => { + it('should render correctly when there are no issues in GitHub', async () => { + const mockApi = { + fetchIssuesByRepoFromGitHub: async () => ({ + backstage: { + issues: { + totalCount: 0, + edges: [], + }, + }, + }), + } as GitHubIssuesApi; + + const apis = [ + [gitHubIssuesApiRef, mockApi], + [catalogApiRef, mockCatalogApi], + ] as const; + + const { getByTestId } = await renderInTestApp( + + + + + , + ); + + expect(getByTestId('no-issues-msg')).toHaveTextContent( + 'Hurray! No Issues 🚀', + ); + }); + + it('should render correctly', async () => { + const testIssue = getTestIssue({ + createdAt: '2020-04-19T10:15:47.614Z', + updatedAt: '2020-04-20T00:15:47.614Z', + }); + + const mockApi = { + fetchIssuesByRepoFromGitHub: async () => ({ + backstage: { + issues: { + totalCount: 1, + edges: [testIssue], + }, + }, + }), + } as GitHubIssuesApi; + const apis = [ + [gitHubIssuesApiRef, mockApi], + [catalogApiRef, mockCatalogApi], + ] as const; + + const { getByText, getByTestId } = await renderInTestApp( + + + + + , + ); + + getByText('All repositories (1 Issue)'); + + expect(getByTestId(`issue-${testIssue.node.url}`)).toHaveTextContent( + testIssue.node.title, + ); + + expect(getByTestId(`issue-${testIssue.node.url}`)).toHaveTextContent( + testIssue.node.repository.nameWithOwner, + ); + + expect(getByTestId(`issue-${testIssue.node.url}`)).toHaveTextContent( + `Created at: 22 hours ago by ${testIssue.node.author.login}`, + ); + + expect(getByTestId(`issue-${testIssue.node.url}`)).toHaveTextContent( + `Last update at: 8 hours ago`, + ); + }); +}); diff --git a/plugins/github-issues/src/components/GitHubIssues/GitHubIssues.tsx b/plugins/github-issues/src/components/GitHubIssues/GitHubIssues.tsx new file mode 100644 index 0000000000..574c15d3b3 --- /dev/null +++ b/plugins/github-issues/src/components/GitHubIssues/GitHubIssues.tsx @@ -0,0 +1,69 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; + +import { Box, IconButton, Typography } from '@material-ui/core'; +import { InfoCard, Progress } from '@backstage/core-components'; +import RefreshIcon from '@material-ui/icons/Refresh'; + +import { useEntityGitHubRepositories } from '../../hooks/useEntityGitHubRepositories'; +import { useGetIssuesByRepoFromGitHub } from '../../hooks/useGetIssuesByRepoFromGitHub'; + +import { IssuesList } from './IssuesList'; +import { NoRepositoriesInfo } from './NoRepositoriesInfo'; + +/** + * @public + */ +export type GitHubIssuesProps = { + itemsPerPage?: number; + itemsPerRepo?: number; +}; + +export const GitHubIssues = (props: GitHubIssuesProps) => { + const { itemsPerPage = 10, itemsPerRepo = 40 } = props; + + const { repositories } = useEntityGitHubRepositories(); + const { + isLoading, + gitHubIssuesByRepo: issuesByRepository, + retry, + } = useGetIssuesByRepoFromGitHub(repositories, itemsPerRepo); + + if (!repositories.length) { + return ; + } + + return ( + + Open GitHub Issues + + + + + } + > + {isLoading && } + + + + ); +}; diff --git a/plugins/github-issues/src/components/GitHubIssues/IssueCard/Assignees.tsx b/plugins/github-issues/src/components/GitHubIssues/IssueCard/Assignees.tsx new file mode 100644 index 0000000000..173c8d9439 --- /dev/null +++ b/plugins/github-issues/src/components/GitHubIssues/IssueCard/Assignees.tsx @@ -0,0 +1,59 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { Typography, Box, Avatar, makeStyles } from '@material-ui/core'; + +type AssigneesProps = { + name?: string; + avatar?: string; +}; + +const useStyles = makeStyles(theme => ({ + small: { + width: theme.spacing(4), + height: theme.spacing(4), + marginLeft: theme.spacing(1), + }, + noAssignees: { + height: theme.spacing(4), + }, +})); + +export const Assignees = (props: AssigneesProps) => { + const { name, avatar } = props; + const classes = useStyles(); + + // todo: many assignees -> NUM assignees + stock images on each other + return name ? ( + + + {name} + + + + ) : ( + + + No assignees + + + ); +}; diff --git a/plugins/github-issues/src/components/GitHubIssues/IssueCard/CommentsCount.tsx b/plugins/github-issues/src/components/GitHubIssues/IssueCard/CommentsCount.tsx new file mode 100644 index 0000000000..80a365cbbb --- /dev/null +++ b/plugins/github-issues/src/components/GitHubIssues/IssueCard/CommentsCount.tsx @@ -0,0 +1,40 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { ChatIcon } from '@backstage/core-components'; +import { Box, Badge } from '@material-ui/core'; + +type CommentsCountProps = { + commentsCount: number; +}; + +export const CommentsCount = (props: CommentsCountProps) => { + const { commentsCount } = props; + + return ( + + + + + + ); +}; diff --git a/plugins/github-issues/src/components/GitHubIssues/IssueCard/IssueCard.tsx b/plugins/github-issues/src/components/GitHubIssues/IssueCard/IssueCard.tsx new file mode 100644 index 0000000000..ccf30a9a84 --- /dev/null +++ b/plugins/github-issues/src/components/GitHubIssues/IssueCard/IssueCard.tsx @@ -0,0 +1,102 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { DateTime } from 'luxon'; + +import { + Box, + Paper, + Typography, + CardActionArea, + Link, +} from '@material-ui/core'; +import { Assignees } from './Assignees'; +import { CommentsCount } from './CommentsCount'; + +import Divider from '@material-ui/core/Divider'; + +type IssueCardProps = { + title: string; + createdAt: string; + updatedAt?: string; + url: string; + authorName: string; + assigneeName?: string; + assigneeAvatar?: string; + authorAvatar?: string; + repositoryName: string; + commentsCount: number; + even: boolean; +}; + +const getElapsedTime = (isoDate: string) => + DateTime.fromISO(isoDate).toRelative(); + +export const IssueCard = (props: IssueCardProps) => { + const { + title, + createdAt, + updatedAt, + url, + assigneeName, + assigneeAvatar, + authorName, + repositoryName, + commentsCount, + } = props; + + return ( + + + + + + + {repositoryName} + + + + + + {title} + + + + + + + Created at: {getElapsedTime(createdAt)} by{' '} + {authorName} + + {updatedAt && ( + + Last update at: {getElapsedTime(updatedAt)} + + )} + + {commentsCount > 0 && ( + + )} + + + + + + ); +}; diff --git a/plugins/github-issues/src/components/GitHubIssues/IssueCard/index.ts b/plugins/github-issues/src/components/GitHubIssues/IssueCard/index.ts new file mode 100644 index 0000000000..5c60abf6ab --- /dev/null +++ b/plugins/github-issues/src/components/GitHubIssues/IssueCard/index.ts @@ -0,0 +1,16 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export { IssueCard } from './IssueCard'; diff --git a/plugins/github-issues/src/components/GitHubIssues/IssuesList/Filters/Filters.tsx b/plugins/github-issues/src/components/GitHubIssues/IssuesList/Filters/Filters.tsx new file mode 100644 index 0000000000..de071ab5bb --- /dev/null +++ b/plugins/github-issues/src/components/GitHubIssues/IssuesList/Filters/Filters.tsx @@ -0,0 +1,67 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import React from 'react'; +import { Select, SelectedItems, SelectItem } from '@backstage/core-components'; +import { makeStyles, Box, Typography } from '@material-ui/core'; + +type RepositoryFiltersProps = { + items: Array; + totalIssuesInGitHub: number; + placeholder: string; + onChange: (active: Array) => void; +}; + +const useStyles = makeStyles(theme => ({ + filters: { + margin: theme.spacing(0, 0, 2, 0), + '& > div': { + maxWidth: '800px', + '& > div': { + maxWidth: '800px', + }, + }, + }, +})); + +const checkSelectedItems: ( + onChange: (active: Array) => void, +) => (active: SelectedItems) => void = onChange => active => { + return onChange(active as Array); +}; + +export const RepositoryFilters = ({ + items, + onChange, + placeholder, +}: RepositoryFiltersProps) => { + const css = useStyles(); + + return ( + + ) => - updateSelected(e?.target?.value) - } - variant="outlined" - className={classes.dropdown} - value={filters.selected} - > - {filterOptions.kind.map(filter => ( - - {filter} - - ))} - - - )} - {filterOptions.lifecycle.length > 0 && ( - - Lifecycle - - {filterOptions.lifecycle.map(filter => ( - updateChecked(filter)} - > - - - - ))} - - - )} - - ); -}; diff --git a/plugins/search/src/components/Filters/FiltersButton.tsx b/plugins/search/src/components/Filters/FiltersButton.tsx deleted file mode 100644 index 890c787689..0000000000 --- a/plugins/search/src/components/Filters/FiltersButton.tsx +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import FilterListIcon from '@material-ui/icons/FilterList'; -import { makeStyles, IconButton, Typography } from '@material-ui/core'; - -const useStyles = makeStyles(theme => ({ - filters: { - width: '250px', - display: 'flex', - }, - icon: { - margin: theme.spacing(-1, 0, 0, 0), - }, -})); - -/** - * Props for {@link FiltersButton}. - * - * @public - * @deprecated This type and corresponding component will be removed in a - * future release. - */ -export type FiltersButtonProps = { - numberOfSelectedFilters: number; - handleToggleFilters: () => void; -}; - -/** - * @public - * @deprecated See `SearchFilter` in `@backstage/plugin-search-react` instead. - */ -export const FiltersButton = ({ - numberOfSelectedFilters, - handleToggleFilters, -}: FiltersButtonProps) => { - const classes = useStyles(); - - return ( -
- - - - - Filters ({numberOfSelectedFilters ? numberOfSelectedFilters : 0}) - -
- ); -}; diff --git a/plugins/search/src/components/LegacySearchPage/Filters/Filters.tsx b/plugins/search/src/components/LegacySearchPage/Filters/Filters.tsx deleted file mode 100644 index a0ca4914a2..0000000000 --- a/plugins/search/src/components/LegacySearchPage/Filters/Filters.tsx +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { - makeStyles, - Typography, - Divider, - Card, - CardHeader, - Button, - CardContent, - Select, - Checkbox, - List, - ListItem, - ListItemText, - MenuItem, -} from '@material-ui/core'; - -const useStyles = makeStyles(theme => ({ - filters: { - background: 'transparent', - boxShadow: '0px 0px 0px 0px', - }, - checkbox: { - padding: theme.spacing(0, 1, 0, 1), - }, - dropdown: { - width: '100%', - }, -})); - -export type FiltersState = { - selected: string; - checked: Array; -}; - -export type FilterOptions = { - kind: Array; - lifecycle: Array; -}; - -type FiltersProps = { - filters: FiltersState; - filterOptions: FilterOptions; - resetFilters: () => void; - updateSelected: (filter: string) => void; - updateChecked: (filter: string) => void; -}; - -export const Filters = ({ - filters, - filterOptions, - resetFilters, - updateSelected, - updateChecked, -}: FiltersProps) => { - const classes = useStyles(); - - return ( - - Filters} - action={ - - } - /> - - {filterOptions.kind.length === 0 && filterOptions.lifecycle.length === 0 && ( - - - Filters cannot be applied to available results - - - )} - {filterOptions.kind.length > 0 && ( - - Kind - - - )} - {filterOptions.lifecycle.length > 0 && ( - - Lifecycle - - {filterOptions.lifecycle.map(filter => ( - updateChecked(filter)} - > - - - - ))} - - - )} - - ); -}; diff --git a/plugins/search/src/components/LegacySearchPage/Filters/FiltersButton.tsx b/plugins/search/src/components/LegacySearchPage/Filters/FiltersButton.tsx deleted file mode 100644 index 1c2829defe..0000000000 --- a/plugins/search/src/components/LegacySearchPage/Filters/FiltersButton.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import FilterListIcon from '@material-ui/icons/FilterList'; -import { makeStyles, IconButton, Typography } from '@material-ui/core'; - -const useStyles = makeStyles(theme => ({ - filters: { - width: '250px', - display: 'flex', - }, - icon: { - margin: theme.spacing(-1, 0, 0, 0), - }, -})); - -type FiltersButtonProps = { - numberOfSelectedFilters: number; - handleToggleFilters: () => void; -}; - -export const FiltersButton = ({ - numberOfSelectedFilters, - handleToggleFilters, -}: FiltersButtonProps) => { - const classes = useStyles(); - - return ( -
- - - - - Filters ({numberOfSelectedFilters ? numberOfSelectedFilters : 0}) - -
- ); -}; diff --git a/plugins/search/src/components/LegacySearchPage/LegacySearchBar.tsx b/plugins/search/src/components/LegacySearchPage/LegacySearchBar.tsx deleted file mode 100644 index 44fb006af3..0000000000 --- a/plugins/search/src/components/LegacySearchPage/LegacySearchBar.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { makeStyles } from '@material-ui/core/styles'; -import { Paper } from '@material-ui/core'; -import InputBase from '@material-ui/core/InputBase'; -import IconButton from '@material-ui/core/IconButton'; -import SearchIcon from '@material-ui/icons/Search'; -import ClearButton from '@material-ui/icons/Clear'; - -const useStyles = makeStyles(() => ({ - root: { - display: 'flex', - alignItems: 'center', - }, - input: { - flex: 1, - }, -})); - -type SearchBarProps = { - searchQuery: string; - handleSearch: any; - handleClearSearchBar: any; -}; - -export const SearchBar = ({ - searchQuery, - handleSearch, - handleClearSearchBar, -}: SearchBarProps) => { - const classes = useStyles(); - - return ( - handleSearch(e)} - className={classes.root} - > - - - - handleSearch(e)} - inputProps={{ 'aria-label': 'search backstage' }} - /> - handleClearSearchBar()}> - - - - ); -}; diff --git a/plugins/search/src/components/LegacySearchPage/LegacySearchPage.tsx b/plugins/search/src/components/LegacySearchPage/LegacySearchPage.tsx deleted file mode 100644 index 09a33b9b74..0000000000 --- a/plugins/search/src/components/LegacySearchPage/LegacySearchPage.tsx +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Grid } from '@material-ui/core'; -import React, { useEffect, useState } from 'react'; -import useDebounce from 'react-use/lib/useDebounce'; -import { SearchBar } from './LegacySearchBar'; -import { SearchResult } from './LegacySearchResult'; -import { - Content, - Header, - Page, - useQueryParamState, -} from '@backstage/core-components'; - -/** - * @deprecated This SearchPage, powered directly by the Catalog API, will be - * removed from a future release of this plugin. - */ -export const LegacySearchPage = () => { - const [queryString, setQueryString] = useQueryParamState('query'); - const [searchQuery, setSearchQuery] = useState(queryString ?? ''); - - const handleSearch = (event: React.ChangeEvent) => { - event.preventDefault(); - setSearchQuery(event.target.value); - }; - - useEffect(() => setSearchQuery(queryString ?? ''), [queryString]); - - useDebounce( - () => { - setQueryString(searchQuery); - }, - 200, - [searchQuery], - ); - - const handleClearSearchBar = () => { - setSearchQuery(''); - }; - - return ( - -
- - - - - - - - - - - - ); -}; diff --git a/plugins/search/src/components/LegacySearchPage/LegacySearchResult.tsx b/plugins/search/src/components/LegacySearchPage/LegacySearchResult.tsx deleted file mode 100644 index ba92dba710..0000000000 --- a/plugins/search/src/components/LegacySearchPage/LegacySearchResult.tsx +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright 2020 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -import { Divider, Grid, makeStyles, Typography } from '@material-ui/core'; -import { Alert } from '@material-ui/lab'; -import React, { useEffect, useState } from 'react'; -import useAsync from 'react-use/lib/useAsync'; -import { catalogApiRef } from '@backstage/plugin-catalog-react'; - -import { Filters, FiltersButton, FiltersState } from './Filters'; -import { Entity, DEFAULT_NAMESPACE } from '@backstage/catalog-model'; - -import { - EmptyState, - Link, - Progress, - Table, - TableColumn, -} from '@backstage/core-components'; -import { useApi } from '@backstage/core-plugin-api'; - -type Result = { - name: string; - description: string | undefined; - owner: string | undefined; - kind: string; - lifecycle: string | undefined; - url: string; -}; -type SearchResults = Array; - -const useStyles = makeStyles(theme => ({ - searchQuery: { - color: theme.palette.text.primary, - background: theme.palette.background.default, - borderRadius: '10%', - }, - tableHeader: { - margin: theme.spacing(1, 0, 0, 0), - display: 'flex', - }, - divider: { - width: '1px', - margin: theme.spacing(0, 2), - padding: theme.spacing(2, 0), - }, -})); - -type SearchResultProps = { - searchQuery?: string; -}; - -type TableHeaderProps = { - searchQuery?: string; - numberOfSelectedFilters: number; - numberOfResults: number; - handleToggleFilters: () => void; -}; - -// TODO: move out column to make the search result component more generic -const columns: TableColumn[] = [ - { - title: 'Name', - field: 'name', - highlight: true, - render: (result: Partial) => ( - {result.name} - ), - }, - { - title: 'Description', - field: 'description', - }, - { - title: 'Owner', - field: 'owner', - }, - { - title: 'Kind', - field: 'kind', - }, - { - title: 'LifeCycle', - field: 'lifecycle', - }, -]; - -const TableHeader = ({ - searchQuery, - numberOfSelectedFilters, - numberOfResults, - handleToggleFilters, -}: TableHeaderProps) => { - const classes = useStyles(); - - return ( -
- - - - {searchQuery ? ( - - {`${numberOfResults} `} - {numberOfResults > 1 ? `results for ` : `result for `} - "{searchQuery}"{' '} - - ) : ( - {`${numberOfResults} results`} - )} - -
- ); -}; - -export const SearchResult = ({ searchQuery }: SearchResultProps) => { - const catalogApi = useApi(catalogApiRef); - - const [showFilters, toggleFilters] = useState(false); - const [selectedFilters, setSelectedFilters] = useState({ - selected: '', - checked: [], - }); - - const [filteredResults, setFilteredResults] = useState([]); - - const { - loading, - error, - value: results, - } = useAsync(async () => { - const entities = await catalogApi.getEntities(); - return entities.items.map((entity: Entity) => ({ - name: entity.metadata.name, - description: entity.metadata.description, - owner: - typeof entity.spec?.owner === 'string' ? entity.spec?.owner : undefined, - kind: entity.kind, - lifecycle: - typeof entity.spec?.lifecycle === 'string' - ? entity.spec?.lifecycle - : undefined, - url: `/catalog/${ - entity.metadata.namespace?.toLocaleLowerCase('en-US') || - DEFAULT_NAMESPACE - }/${entity.kind.toLocaleLowerCase('en-US')}/${entity.metadata.name}`, - })); - }, []); - - useEffect(() => { - if (results) { - let withFilters = results; - - // apply filters - - // filter on selected - if (selectedFilters.selected !== '') { - withFilters = results.filter((result: Result) => - selectedFilters.selected.includes(result.kind), - ); - } - - // filter on checked - if (selectedFilters.checked.length > 0) { - withFilters = withFilters.filter( - (result: Result) => - result.lifecycle && - selectedFilters.checked.includes(result.lifecycle), - ); - } - - // filter on searchQuery - if (searchQuery) { - withFilters = withFilters.filter( - (result: Result) => - result.name?.toLocaleLowerCase('en-US').includes(searchQuery) || - result.name - ?.toLocaleLowerCase('en-US') - .includes(searchQuery.split(' ').join('-')) || - result.description - ?.toLocaleLowerCase('en-US') - .includes(searchQuery), - ); - } - - setFilteredResults(withFilters); - } - }, [selectedFilters, searchQuery, results]); - if (loading) { - return ; - } - if (error) { - return ( - - Error encountered while fetching search results. {error.toString()} - - ); - } - if (!results || results.length === 0) { - return ; - } - - const resetFilters = () => { - setSelectedFilters({ - selected: '', - checked: [], - }); - }; - - const updateSelected = (filter: string) => { - setSelectedFilters(prevState => ({ - ...prevState, - selected: filter, - })); - }; - - const updateChecked = (filter: string) => { - if (selectedFilters.checked.includes(filter)) { - setSelectedFilters(prevState => ({ - ...prevState, - checked: prevState.checked.filter(item => item !== filter), - })); - return; - } - - setSelectedFilters(prevState => ({ - ...prevState, - checked: [...prevState.checked, filter], - })); - }; - - const filterOptions = results.reduce( - (acc, curr) => { - if (curr.kind && acc.kind.indexOf(curr.kind) < 0) { - acc.kind.push(curr.kind); - } - if (curr.lifecycle && acc.lifecycle.indexOf(curr.lifecycle) < 0) { - acc.lifecycle.push(curr.lifecycle); - } - return acc; - }, - { - kind: [] as Array, - lifecycle: [] as Array, - }, - ); - - return ( - <> - - {showFilters && ( - - - - )} - -
toggleFilters(!showFilters)} - /> - } - /> - - - - ); -}; diff --git a/plugins/search/src/components/SearchBar/SearchBar.tsx b/plugins/search/src/components/SearchBar/SearchBar.tsx deleted file mode 100644 index a854869976..0000000000 --- a/plugins/search/src/components/SearchBar/SearchBar.tsx +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { useCallback } from 'react'; - -import { InputBaseProps } from '@material-ui/core'; - -import { - SearchBarBase as RealSearchBarBase, - useSearch, -} from '@backstage/plugin-search-react'; - -/** - * Props for {@link SearchBarBase}. - * - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export type SearchBarBaseProps = Omit & { - debounceTime?: number; - clearButton?: boolean; - onClear?: () => void; - onSubmit?: () => void; - onChange: (value: string) => void; -}; - -/** - * All search boxes exported by the search plugin are based on the , - * and this one is based on the component from Material UI. - * Recommended if you don't use Search Provider or Search Context. - * - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export const SearchBarBase = RealSearchBarBase; - -/** - * Props for {@link SearchBar}. - * - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export type SearchBarProps = Partial; - -/** - * Recommended search bar when you use the Search Provider or Search Context. - * - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export const SearchBar = ({ onChange, ...props }: SearchBarProps) => { - const { term, setTerm } = useSearch(); - - const handleChange = useCallback( - (newValue: string) => { - if (onChange) { - onChange(newValue); - } else { - setTerm(newValue); - } - }, - [onChange, setTerm], - ); - - return ; -}; diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx deleted file mode 100644 index 15ad348bd4..0000000000 --- a/plugins/search/src/components/SearchFilter/SearchFilter.Autocomplete.test.tsx +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { TestApiProvider } from '@backstage/test-utils'; -import { screen, render, waitFor, within } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import React from 'react'; -import { - SearchContextProvider, - useSearch, - searchApiRef, -} from '@backstage/plugin-search-react'; -import { SearchFilter } from './SearchFilter'; - -const SearchContextFilterSpy = ({ name }: { name: string }) => { - const { filters } = useSearch(); - const value = filters[name]; - return ( - - {Array.isArray(value) ? value.join(',') : value} - - ); -}; - -describe('SearchFilter.Autocomplete', () => { - const query = jest.fn().mockResolvedValue({}); - const emptySearchContext = { - term: '', - types: [], - filters: {}, - }; - - const name = 'field'; - const values = ['value1', 'value2']; - - it('renders as expected', async () => { - render( - - - - - , - ); - - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - await userEvent.click(input); - - await waitFor(() => { - screen.getByRole('listbox'); - }); - - expect(screen.getByRole('option', { name: values[0] })).toBeInTheDocument(); - expect(screen.getByRole('option', { name: values[1] })).toBeInTheDocument(); - }); - - it('renders as expected with async values', async () => { - render( - - - values} /> - - , - ); - - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - await userEvent.click(input); - - await waitFor(() => { - screen.getByRole('listbox'); - }); - - expect(screen.getByRole('option', { name: values[0] })).toBeInTheDocument(); - expect(screen.getByRole('option', { name: values[1] })).toBeInTheDocument(); - }); - - it('does not affect unrelated filter state', async () => { - render( - - - - - - - , - ); - - // The spy should show the initial value. - expect(screen.getByTestId('unrelated-filter-spy')).toHaveTextContent( - 'value', - ); - - // Select a value from the autocomplete filter. - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[1] })); - - // Wait for the autocomplete filter's value to change. - await waitFor(() => { - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values[1], - ); - }); - - // Unrelated filter spy should maintain the same value. - expect(screen.getByTestId('unrelated-filter-spy')).toHaveTextContent( - 'value', - ); - }); - - describe('single', () => { - it('renders as expected with defaultValue', async () => { - render( - - - - - - , - ); - - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - - await waitFor(() => { - expect(input).toHaveValue(values[1]); - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values[1], - ); - }); - }); - - it('renders as expected with initial context', async () => { - render( - - - - - - , - ); - - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - - await waitFor(() => { - expect(input).toHaveValue(values[0]); - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values[0], - ); - }); - }); - - it('sets filter state when selecting a value', async () => { - render( - - - - - - , - ); - - // Select the first option in the autocomplete. - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[0] })); - - // The value should be present in the context. - await waitFor(() => { - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values[0], - ); - }); - - // Click the "Clear" button to remove the value. - const clearButton = within(autocomplete).getByLabelText('Clear'); - await userEvent.click(clearButton); - - // That value should have been unset from the context. - await waitFor(() => { - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent(''); - }); - }); - }); - - describe('multiple', () => { - it('renders as expected with defaultValue', async () => { - render( - - - - - - , - ); - - await waitFor(() => { - expect(screen.getByText(values[0])).toBeInTheDocument(); - expect(screen.getByText(values[1])).toBeInTheDocument(); - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values.join(','), - ); - }); - }); - - it('renders as expected with initial context', async () => { - render( - - - - - - , - ); - - await waitFor(() => { - expect(screen.getByText(values[0])).toBeInTheDocument(); - expect(screen.getByText(values[1])).toBeInTheDocument(); - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values.join(','), - ); - }); - }); - - it('respects tag limit configuration', async () => { - render( - - - - - , - ); - - const autocomplete = screen.getByRole('combobox'); - const input = within(autocomplete).getByRole('textbox'); - - // Select the second value. - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[1] })); - await waitFor(() => { - expect( - screen.getByRole('button', { name: values[1] }), - ).toBeInTheDocument(); - }); - - // Select the first value. - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[0] })); - await waitFor(() => { - expect( - screen.getByRole('button', { name: values[0] }), - ).toBeInTheDocument(); - }); - - // Blur the field and only one tag should be shown with a +1. - input.blur(); - expect( - screen.queryByRole('button', { name: values[0] }), - ).not.toBeInTheDocument(); - expect(screen.getByText('+1')).toBeInTheDocument(); - }); - - it('sets filter state when selecting a value', async () => { - render( - - - - - - , - ); - - const autocomplete = screen.getByRole('combobox'); - - // Select both values in the autocomplete. - const input = within(autocomplete).getByRole('textbox'); - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[0] })); - await userEvent.click(input); - await waitFor(() => { - screen.getByRole('listbox'); - }); - await userEvent.click(screen.getByRole('option', { name: values[1] })); - - // Both options should be present in the context. - await waitFor(() => { - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent( - values.join(','), - ); - }); - - // Click the "Clear" button to remove the value. - const clearButton = within(autocomplete).getByLabelText('Clear'); - await userEvent.click(clearButton); - - // There should be no content in the filter context. - await waitFor(() => { - expect(screen.getByTestId(`${name}-filter-spy`)).toHaveTextContent(''); - }); - }); - }); -}); diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.test.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.test.tsx deleted file mode 100644 index 2d652df483..0000000000 --- a/plugins/search/src/components/SearchFilter/SearchFilter.test.tsx +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React from 'react'; -import { screen, render, waitFor } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { SearchFilter } from './SearchFilter'; - -import { SearchContextProvider } from '@backstage/plugin-search-react'; -import { useApi } from '@backstage/core-plugin-api'; - -jest.mock('@backstage/core-plugin-api', () => ({ - ...jest.requireActual('@backstage/core-plugin-api'), - useApi: jest.fn().mockReturnValue({}), -})); - -describe('SearchFilter', () => { - const initialState = { - term: '', - filters: {}, - types: [], - }; - - const label = 'Field'; - const name = 'field'; - const values = ['value1', 'value2']; - const filters = { unrelated: 'unrelated' }; - - const query = jest.fn().mockResolvedValue({}); - (useApi as jest.Mock).mockReturnValue({ query: query }); - - afterAll(() => { - jest.resetAllMocks(); - }); - - it('Check that element was rendered and received props', async () => { - const CustomFilter = (props: { name: string }) =>
{props.name}
; - - render(); - - expect(screen.getByRole('heading', { name })).toBeInTheDocument(); - }); - - describe('Checkbox', () => { - it('Renders field name and values when provided as props', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - expect( - screen.getByRole('checkbox', { name: values[0] }), - ).toBeInTheDocument(); - expect( - screen.getByRole('checkbox', { name: values[1] }), - ).toBeInTheDocument(); - }); - - it('Renders correctly based on filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - expect( - screen.getByRole('checkbox', { name: values[0] }), - ).not.toBeChecked(); - expect(screen.getByRole('checkbox', { name: values[1] })).toBeChecked(); - }); - - it('Renders correctly based on defaultValue', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - expect(screen.getByRole('checkbox', { name: values[0] })).toBeChecked(); - expect( - screen.getByRole('checkbox', { name: values[1] }), - ).not.toBeChecked(); - }); - - it('Checking / unchecking a value sets filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - const checkBox = screen.getByRole('checkbox', { name: values[0] }); - - // Check the box. - await userEvent.click(checkBox); - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters: { field: [values[0]] } }), - ); - }); - - // Uncheck the box. - await userEvent.click(checkBox); - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters: {} }), - ); - }); - }); - - it('Checking / unchecking a value maintains unrelated filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - const checkBox = screen.getByRole('checkbox', { name: values[0] }); - - // Check the box. - await userEvent.click(checkBox); - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ - filters: { ...filters, field: [values[0]] }, - }), - ); - }); - - // Uncheck the box. - await userEvent.click(checkBox); - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters }), - ); - }); - }); - }); - - describe('Select', () => { - it('Renders field name and values when provided as props', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('button')); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - expect( - screen.getByRole('option', { name: values[0] }), - ).toBeInTheDocument(); - expect( - screen.getByRole('option', { name: values[1] }), - ).toBeInTheDocument(); - }); - - it('Renders values when provided asynchronously', async () => { - render( - - values} - /> - , - ); - - await waitFor(() => { - expect(screen.getByRole('button')).toBeInTheDocument(); - expect( - screen.getByRole('button').getAttribute('aria-disabled'), - ).not.toBe('true'); - }); - - await userEvent.click(screen.getByRole('button')); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - expect( - screen.getByRole('option', { name: values[0] }), - ).toBeInTheDocument(); - expect( - screen.getByRole('option', { name: values[1] }), - ).toBeInTheDocument(); - }); - - it('Renders correctly based on filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('button')); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - expect(screen.getByRole('option', { name: values[0] })).toHaveAttribute( - 'aria-selected', - 'true', - ); - expect( - screen.getByRole('option', { name: values[1] }), - ).not.toHaveAttribute('aria-selected'); - expect(screen.getByRole('option', { name: 'All' })).not.toHaveAttribute( - 'aria-selected', - ); - }); - - it('Renders correctly based on defaultValue', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('button')); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - expect(screen.getByRole('option', { name: values[0] })).toHaveAttribute( - 'aria-selected', - 'true', - ); - expect( - screen.getByRole('option', { name: values[1] }), - ).not.toHaveAttribute('aria-selected'); - expect(screen.getByRole('option', { name: 'All' })).not.toHaveAttribute( - 'aria-selected', - ); - }); - - it('Selecting a value sets filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - const button = screen.getByRole('button'); - - await userEvent.click(button); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('option', { name: values[0] })); - - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ - filters: { [name]: values[0] }, - }), - ); - }); - - await userEvent.click(button); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('option', { name: 'All' })); - - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ - filters: {}, - }), - ); - }); - }); - - it('Selecting a value maintains unrelated filter state', async () => { - render( - - - , - ); - - await waitFor(() => { - expect(screen.getByText(label)).toBeInTheDocument(); - }); - - const button = screen.getByRole('button'); - - await userEvent.click(button); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('option', { name: values[0] })); - - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ - filters: { ...filters, [name]: values[0] }, - }), - ); - }); - - await userEvent.click(button); - - await waitFor(() => { - expect(screen.getByRole('listbox')).toBeInTheDocument(); - }); - - await userEvent.click(screen.getByRole('option', { name: 'All' })); - - await waitFor(() => { - expect(query).toHaveBeenLastCalledWith( - expect.objectContaining({ filters }), - ); - }); - }); - }); -}); diff --git a/plugins/search/src/components/SearchFilter/SearchFilter.tsx b/plugins/search/src/components/SearchFilter/SearchFilter.tsx deleted file mode 100644 index e58bbd5c14..0000000000 --- a/plugins/search/src/components/SearchFilter/SearchFilter.tsx +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { ReactElement } from 'react'; - -import { - AutocompleteFilter, - CheckboxFilter, - SearchAutocompleteFilterProps, - SelectFilter, -} from '@backstage/plugin-search-react'; - -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export type SearchFilterComponentProps = { - className?: string; - name: string; - label?: string; - /** - * Either an array of values directly, or an async function to return a list - * of values to be used in the filter. In the autocomplete filter, the last - * input value is provided as an input to allow values to be filtered. This - * function is debounced and values cached. - */ - values?: string[] | ((partial: string) => Promise); - defaultValue?: string[] | string | null; - /** - * Debounce time in milliseconds, used when values is an async callback. - * Defaults to 250ms. - */ - valuesDebounceMs?: number; -}; - -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export type SearchFilterWrapperProps = SearchFilterComponentProps & { - component: (props: SearchFilterComponentProps) => ReactElement; - debug?: boolean; -}; - -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -const SearchFilter = ({ - component: Element, - ...props -}: SearchFilterWrapperProps) => ; - -/** - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -SearchFilter.Checkbox = ( - props: Omit & - SearchFilterComponentProps, -) => ; - -/** - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -SearchFilter.Select = ( - props: Omit & - SearchFilterComponentProps, -) => ; - -/** - * A control surface for a given filter field name, rendered as an autocomplete - * textfield. A hard-coded list of values may be provided, or an async function - * which returns values may be provided instead. - * - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -SearchFilter.Autocomplete = (props: SearchAutocompleteFilterProps) => ( - -); - -export { SearchFilter }; diff --git a/plugins/search/src/components/SearchModal/SearchModal.stories.tsx b/plugins/search/src/components/SearchModal/SearchModal.stories.tsx index aad018c334..eac01cceb8 100644 --- a/plugins/search/src/components/SearchModal/SearchModal.stories.tsx +++ b/plugins/search/src/components/SearchModal/SearchModal.stories.tsx @@ -27,8 +27,8 @@ import { import { makeStyles } from '@material-ui/core/styles'; import React, { ComponentType } from 'react'; import { rootRouteRef } from '../../plugin'; -import { SearchBar } from '../SearchBar'; import { + SearchBar, DefaultResultListItem, searchApiRef, MockSearchApi, diff --git a/plugins/search/src/components/SearchPage/SearchPage.test.tsx b/plugins/search/src/components/SearchPage/SearchPage.test.tsx index 59e6e99aaf..459a541cbd 100644 --- a/plugins/search/src/components/SearchPage/SearchPage.test.tsx +++ b/plugins/search/src/components/SearchPage/SearchPage.test.tsx @@ -16,7 +16,7 @@ import { renderInTestApp } from '@backstage/test-utils'; import React from 'react'; -import { useLocation, useOutlet } from 'react-router'; +import { useLocation } from 'react-router'; import { useSearch } from '@backstage/plugin-search-react'; import { SearchPage } from './SearchPage'; @@ -50,11 +50,6 @@ jest.mock('@backstage/plugin-search-react', () => ({ }), })); -jest.mock('../LegacySearchPage', () => ({ - ...jest.requireActual('@backstage/plugin-search-react'), - LegacySearchPage: jest.fn().mockReturnValue('LegacySearchPageMock'), -})); - describe('SearchPage', () => { const origReplaceState = window.history.replaceState; @@ -96,13 +91,6 @@ describe('SearchPage', () => { expect(getByText('Route Children')).toBeInTheDocument(); }); - it('renders legacy search when no router children are provided', async () => { - (useOutlet as jest.Mock).mockReturnValueOnce(null); - const { getByText } = await renderInTestApp(); - - expect(getByText('LegacySearchPageMock')).toBeInTheDocument(); - }); - it('replaces window history with expected query parameters', async () => { (useSearch as jest.Mock).mockReturnValueOnce({ term: 'bieber', diff --git a/plugins/search/src/components/SearchPage/SearchPage.tsx b/plugins/search/src/components/SearchPage/SearchPage.tsx index 7145c7a5ef..f267918e12 100644 --- a/plugins/search/src/components/SearchPage/SearchPage.tsx +++ b/plugins/search/src/components/SearchPage/SearchPage.tsx @@ -23,7 +23,6 @@ import { useSearch, } from '@backstage/plugin-search-react'; import { JsonObject } from '@backstage/types'; -import { LegacySearchPage } from '../LegacySearchPage'; export const UrlUpdater = () => { const location = useLocation(); @@ -96,7 +95,7 @@ export const SearchPage = () => { return ( - {outlet || } + {outlet} ); }; diff --git a/plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx b/plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx deleted file mode 100644 index b1cad8d748..0000000000 --- a/plugins/search/src/components/SearchResultPager/SearchResultPager.test.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { renderInTestApp } from '@backstage/test-utils'; -import { waitFor } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import React from 'react'; -import { useSearch } from '@backstage/plugin-search-react'; -import { SearchResultPager } from './SearchResultPager'; - -jest.mock('@backstage/plugin-search-react', () => ({ - ...jest.requireActual('@backstage/plugin-search-react'), - useSearch: jest.fn().mockReturnValue({ - result: {}, - }), -})); - -describe('SearchResultPager', () => { - it('renders pager buttons', async () => { - const fetchNextPage = jest.fn(); - const fetchPreviousPage = jest.fn(); - (useSearch as jest.Mock).mockReturnValueOnce({ - result: { loading: false, value: [] }, - fetchNextPage, - fetchPreviousPage, - }); - - const { getByLabelText } = await renderInTestApp(); - - await waitFor(() => { - expect(getByLabelText('previous page')).toBeInTheDocument(); - }); - await userEvent.click(getByLabelText('previous page')); - expect(fetchPreviousPage).toBeCalled(); - - await waitFor(() => { - expect(getByLabelText('next page')).toBeInTheDocument(); - }); - await userEvent.click(getByLabelText('next page')); - - expect(fetchNextPage).toBeCalled(); - }); -}); diff --git a/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx b/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx deleted file mode 100644 index 287e485dd1..0000000000 --- a/plugins/search/src/components/SearchResultPager/SearchResultPager.tsx +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2021 The Backstage Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { Button, makeStyles } from '@material-ui/core'; -import ArrowBackIosIcon from '@material-ui/icons/ArrowBackIos'; -import ArrowForwardIosIcon from '@material-ui/icons/ArrowForwardIos'; -import React from 'react'; -import { useSearch } from '@backstage/plugin-search-react'; - -const useStyles = makeStyles(theme => ({ - root: { - display: 'flex', - justifyContent: 'space-between', - gap: theme.spacing(2), - margin: theme.spacing(2, 0), - }, -})); - -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export const SearchResultPager = () => { - const { fetchNextPage, fetchPreviousPage } = useSearch(); - const classes = useStyles(); - - if (!fetchNextPage && !fetchPreviousPage) { - return <>; - } - - return ( - - ); -}; diff --git a/plugins/search/src/index.ts b/plugins/search/src/index.ts index fd0e70c61a..8e1db7c2b8 100644 --- a/plugins/search/src/index.ts +++ b/plugins/search/src/index.ts @@ -20,25 +20,8 @@ * @packageDocumentation */ -export { Filters, FiltersButton } from './components/Filters'; -export type { - FilterOptions, - FiltersState, - FiltersProps, - FiltersButtonProps, -} from './components/Filters'; export type { HomePageSearchBarProps } from './components/HomePageComponent'; -export { SearchBar, SearchBarBase } from './components/SearchBar'; -export type { - SearchBarBaseProps, - SearchBarProps, -} from './components/SearchBar'; -export { SearchFilter } from './components/SearchFilter'; -export type { - SearchAutocompleteFilterProps, - SearchFilterComponentProps, - SearchFilterWrapperProps, -} from './components/SearchFilter'; + export { SearchModal, SearchModalProvider, @@ -51,7 +34,6 @@ export type { SearchModalValue, } from './components/SearchModal'; export { SearchPage as Router } from './components/SearchPage'; -export { SearchResultPager } from './components/SearchResultPager'; export { SearchType } from './components/SearchType'; export type { SearchTypeAccordionProps, @@ -63,11 +45,9 @@ export type { SidebarSearchProps } from './components/SidebarSearch'; export type { SidebarSearchModalProps } from './components/SidebarSearchModal'; export { - DefaultResultListItem, HomePageSearchBar, SearchPage, searchPlugin as plugin, searchPlugin, - SearchResult, SidebarSearchModal, } from './plugin'; diff --git a/plugins/search/src/plugin.ts b/plugins/search/src/plugin.ts index 19fd501129..07a645f73e 100644 --- a/plugins/search/src/plugin.ts +++ b/plugins/search/src/plugin.ts @@ -15,11 +15,7 @@ */ import { SearchClient } from './apis'; -import { - searchApiRef, - SearchResult as RealSearchResult, - DefaultResultListItem as RealDefaultResultListItem, -} from '@backstage/plugin-search-react'; +import { searchApiRef } from '@backstage/plugin-search-react'; import { createApiFactory, createPlugin, @@ -64,12 +60,6 @@ export const SearchPage = searchPlugin.provide( }), ); -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export const SearchResult = RealSearchResult; - /** * @public */ @@ -85,12 +75,6 @@ export const SidebarSearchModal = searchPlugin.provide( }), ); -/** - * @public - * @deprecated Import from `@backstage/plugin-search-react` instead. - */ -export const DefaultResultListItem = RealDefaultResultListItem; - /** * @public */ diff --git a/plugins/sentry/CHANGELOG.md b/plugins/sentry/CHANGELOG.md index 02052d7593..d7327602f0 100644 --- a/plugins/sentry/CHANGELOG.md +++ b/plugins/sentry/CHANGELOG.md @@ -1,5 +1,68 @@ # @backstage/plugin-sentry +## 0.4.1 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.4.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.4.1-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.4.0 + +### Minor Changes + +- 1b7c691a3b: Added the possibility to specify organization per component, now the annotation `sentry.io/project-slug` can have the format of `[organization]/[project-slug]` or just `[project-slug]`. + + **BREAKING**: The method `fetchIssue` changed the signature: + + ```diff + export interface SentryApi { + fetchIssues( + - project: string, + - statsFor: string, + - query?: string, + + entity: Entity, + + options: { + + statsFor: string; + + query?: string; + + }, + ): Promise; + } + ``` + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.4.0-next.3 ### Minor Changes diff --git a/plugins/sentry/api-report.md b/plugins/sentry/api-report.md index 625db39959..bd77c46aa6 100644 --- a/plugins/sentry/api-report.md +++ b/plugins/sentry/api-report.md @@ -42,8 +42,6 @@ export class MockSentryApi implements SentryApi { fetchIssues(): Promise; } -// Warning: (ae-missing-release-tag) "ProductionSentryApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export class ProductionSentryApi implements SentryApi { constructor( @@ -61,13 +59,9 @@ export class ProductionSentryApi implements SentryApi { ): Promise; } -// Warning: (ae-missing-release-tag) "Router" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const Router: ({ entity }: { entity: Entity }) => JSX.Element; +export const Router: (props: { entity: Entity }) => JSX.Element; -// Warning: (ae-missing-release-tag) "SentryApi" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export interface SentryApi { // (undocumented) @@ -80,8 +74,6 @@ export interface SentryApi { ): Promise; } -// Warning: (ae-missing-release-tag) "sentryApiRef" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) export const sentryApiRef: ApiRef; @@ -121,30 +113,21 @@ export type SentryIssue = { statusDetails: any; }; -// Warning: (ae-missing-release-tag) "SentryIssuesWidget" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const SentryIssuesWidget: ({ - entity, - statsFor, - tableOptions, - variant, - query, -}: { +export const SentryIssuesWidget: (props: { entity: Entity; statsFor: '24h' | '14d' | ''; tableOptions: Options; - variant?: InfoCardVariants | undefined; - query?: string | undefined; + variant?: InfoCardVariants; + query?: string; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "sentryPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) const sentryPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; export { sentryPlugin as plugin }; diff --git a/plugins/sentry/package.json b/plugins/sentry/package.json index 4990827960..cc33c8dc13 100644 --- a/plugins/sentry/package.json +++ b/plugins/sentry/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sentry", "description": "A Backstage plugin that integrates towards Sentry", - "version": "0.4.0-next.3", + "version": "0.4.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,11 +35,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-table/core": "^3.1.0", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -53,19 +53,19 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", - "@types/luxon": "^2.0.4", + "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/sentry/src/api/production-api.ts b/plugins/sentry/src/api/production-api.ts index da77f8a47d..7fe4afdf98 100644 --- a/plugins/sentry/src/api/production-api.ts +++ b/plugins/sentry/src/api/production-api.ts @@ -20,6 +20,7 @@ import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { getProjectSlug, getOrganization } from './annotations'; +/** @public */ export class ProductionSentryApi implements SentryApi { constructor( private readonly discoveryApi: DiscoveryApi, diff --git a/plugins/sentry/src/api/sentry-api.ts b/plugins/sentry/src/api/sentry-api.ts index 507803804d..73f1301cad 100644 --- a/plugins/sentry/src/api/sentry-api.ts +++ b/plugins/sentry/src/api/sentry-api.ts @@ -18,10 +18,12 @@ import { SentryIssue } from './sentry-issue'; import { createApiRef } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; +/** @public */ export const sentryApiRef = createApiRef({ id: 'plugin.sentry.service', }); +/** @public */ export interface SentryApi { fetchIssues( entity: Entity, diff --git a/plugins/sentry/src/components/Router.tsx b/plugins/sentry/src/components/Router.tsx index 2a3172824a..e683a6c7fa 100644 --- a/plugins/sentry/src/components/Router.tsx +++ b/plugins/sentry/src/components/Router.tsx @@ -19,14 +19,15 @@ import { Entity } from '@backstage/catalog-model'; import { Route, Routes } from 'react-router'; import { SentryIssuesWidget } from './SentryIssuesWidget'; -export const Router = ({ entity }: { entity: Entity }) => { +/** @public */ +export const Router = (props: { entity: Entity }) => { return ( ; variant?: InfoCardVariants; query?: string; }) => { + const { + entity, + statsFor, + tableOptions, + variant = 'gridItem', + query = '', + } = props; const errorApi = useApi(errorApiRef); const sentryApi = useApi(sentryApiRef); diff --git a/plugins/sentry/src/plugin.ts b/plugins/sentry/src/plugin.ts index 981745c8fe..51957b87a3 100644 --- a/plugins/sentry/src/plugin.ts +++ b/plugins/sentry/src/plugin.ts @@ -24,10 +24,12 @@ import { identityApiRef, } from '@backstage/core-plugin-api'; +/** @public */ export const rootRouteRef = createRouteRef({ id: 'sentry', }); +/** @public */ export const sentryPlugin = createPlugin({ id: 'sentry', apis: [ diff --git a/plugins/shortcuts/CHANGELOG.md b/plugins/shortcuts/CHANGELOG.md index b10f277885..9ea824276e 100644 --- a/plugins/shortcuts/CHANGELOG.md +++ b/plugins/shortcuts/CHANGELOG.md @@ -1,5 +1,65 @@ # @backstage/plugin-shortcuts +## 0.3.0 + +### Minor Changes + +- 5b769fddb5: Internal observable replaced with a mapping from the storage API. This fixes shortcuts initialization when using firestore. + + `ShortcutApi.get` method, that returns an immediate snapshot of shortcuts, made public. + + Example of how to get and observe `shortcuts`: + + ```typescript + const shortcutApi = useApi(shortcutsApiRef); + const shortcuts = useObservable(shortcutApi.shortcut$(), shortcutApi.get()); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.3.0-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.3.0-next.0 + +### Minor Changes + +- 5b769fddb5: Internal observable replaced with a mapping from the storage API. This fixes shortcuts initialization when using firestore. + + `ShortcutApi.get` method, that returns an immediate snapshot of shortcuts, made public. + + Example of how to get and observe `shortcuts`: + + ```typescript + const shortcutApi = useApi(shortcutsApiRef); + const shortcuts = useObservable(shortcutApi.shortcut$(), shortcutApi.get()); + ``` + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.2.8 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + ## 0.2.8-next.3 ### Patch Changes diff --git a/plugins/shortcuts/api-report.md b/plugins/shortcuts/api-report.md index 4b5a8e74df..7f81df835d 100644 --- a/plugins/shortcuts/api-report.md +++ b/plugins/shortcuts/api-report.md @@ -9,7 +9,7 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { BackstagePlugin } from '@backstage/core-plugin-api'; import { IconComponent } from '@backstage/core-plugin-api'; import { Observable } from '@backstage/types'; -import ObservableImpl from 'zen-observable'; +import { default as Observable_2 } from 'zen-observable'; import { StorageApi } from '@backstage/core-plugin-api'; // Warning: (ae-missing-release-tag) "LocalStoredShortcuts" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -20,11 +20,13 @@ export class LocalStoredShortcuts implements ShortcutApi { // (undocumented) add(shortcut: Omit): Promise; // (undocumented) + get(): Shortcut[]; + // (undocumented) getColor(url: string): string; // (undocumented) remove(id: string): Promise; // (undocumented) - shortcut$(): ObservableImpl; + shortcut$(): Observable_2; // (undocumented) update(shortcut: Shortcut): Promise; } @@ -43,6 +45,7 @@ export type Shortcut = { // @public (undocumented) export interface ShortcutApi { add(shortcut: Omit): Promise; + get(): Shortcut[]; getColor(url: string): string; remove(id: string): Promise; shortcut$(): Observable; @@ -62,7 +65,7 @@ export const shortcutsApiRef: ApiRef; // Warning: (ae-missing-release-tag) "shortcutsPlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const shortcutsPlugin: BackstagePlugin<{}, {}>; +export const shortcutsPlugin: BackstagePlugin<{}, {}, {}>; // @public export interface ShortcutsProps { diff --git a/plugins/shortcuts/package.json b/plugins/shortcuts/package.json index 1d864a9e67..24ac74f9aa 100644 --- a/plugins/shortcuts/package.json +++ b/plugins/shortcuts/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-shortcuts", "description": "A Backstage plugin that provides a shortcuts feature to the sidebar", - "version": "0.2.8-next.3", + "version": "0.3.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,9 +24,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -42,17 +42,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/shortcuts/src/Shortcuts.tsx b/plugins/shortcuts/src/Shortcuts.tsx index b8af1f2e29..28aa33e8f2 100644 --- a/plugins/shortcuts/src/Shortcuts.tsx +++ b/plugins/shortcuts/src/Shortcuts.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { useMemo } from 'react'; +import React from 'react'; import useObservable from 'react-use/lib/useObservable'; import PlayListAddIcon from '@material-ui/icons/PlaylistAdd'; import { ShortcutItem } from './ShortcutItem'; @@ -39,9 +39,7 @@ export interface ShortcutsProps { export const Shortcuts = (props: ShortcutsProps) => { const shortcutApi = useApi(shortcutsApiRef); - const shortcuts = useObservable( - useMemo(() => shortcutApi.shortcut$(), [shortcutApi]), - ); + const shortcuts = useObservable(shortcutApi.shortcut$(), shortcutApi.get()); const [anchorEl, setAnchorEl] = React.useState(); const loading = Boolean(!shortcuts); diff --git a/plugins/shortcuts/src/api/LocalStoredShortcuts.test.ts b/plugins/shortcuts/src/api/LocalStoredShortcuts.test.ts index c8401e8b1a..dbea91863c 100644 --- a/plugins/shortcuts/src/api/LocalStoredShortcuts.test.ts +++ b/plugins/shortcuts/src/api/LocalStoredShortcuts.test.ts @@ -27,17 +27,22 @@ describe('LocalStoredShortcuts', () => { ); const shortcut: Shortcut = { id: 'id', title: 'title', url: '/url' }; - await shortcutApi.add(shortcut); + const observerNextHandler = jest.fn(); await new Promise(resolve => { - const subscription = shortcutApi.shortcut$().subscribe(data => { - expect(data).toEqual( - expect.arrayContaining([{ ...shortcut, id: expect.anything() }]), - ); - subscription.unsubscribe(); - resolve(); + shortcutApi.shortcut$().subscribe({ + next: data => { + observerNextHandler(data); + resolve(); + }, }); + shortcutApi.add(shortcut); }); + + expect(observerNextHandler).toHaveBeenCalledTimes(1); + expect(observerNextHandler).toHaveBeenCalledWith( + expect.arrayContaining([{ ...shortcut, id: expect.anything() }]), + ); }); it('should add shortcuts with ids', async () => { diff --git a/plugins/shortcuts/src/api/LocalStoredShortcuts.ts b/plugins/shortcuts/src/api/LocalStoredShortcuts.ts index ef54f68acd..82f4b7dd1a 100644 --- a/plugins/shortcuts/src/api/LocalStoredShortcuts.ts +++ b/plugins/shortcuts/src/api/LocalStoredShortcuts.ts @@ -15,11 +15,11 @@ */ import { pageTheme } from '@backstage/theme'; -import ObservableImpl from 'zen-observable'; import { v4 as uuid } from 'uuid'; import { ShortcutApi } from './ShortcutApi'; import { Shortcut } from '../types'; import { StorageApi } from '@backstage/core-plugin-api'; +import Observable from 'zen-observable'; /** * Implementation of the ShortcutApi that uses the StorageApi to store shortcuts. @@ -28,7 +28,15 @@ export class LocalStoredShortcuts implements ShortcutApi { constructor(private readonly storageApi: StorageApi) {} shortcut$() { - return this.observable; + return Observable.from(this.storageApi.observe$('items')).map( + snapshot => snapshot.value ?? [], + ); + } + + get() { + return Array.from( + this.storageApi.snapshot('items').value ?? [], + ).sort((a, b) => (a.title >= b.title ? 1 : -1)); } async add(shortcut: Omit) { @@ -36,14 +44,12 @@ export class LocalStoredShortcuts implements ShortcutApi { shortcuts.push({ ...shortcut, id: uuid() }); await this.storageApi.set('items', shortcuts); - this.notify(); } async remove(id: string) { const shortcuts = this.get().filter(s => s.id !== id); await this.storageApi.set('items', shortcuts); - this.notify(); } async update(shortcut: Shortcut) { @@ -51,7 +57,6 @@ export class LocalStoredShortcuts implements ShortcutApi { shortcuts.push(shortcut); await this.storageApi.set('items', shortcuts); - this.notify(); } getColor(url: string) { @@ -63,33 +68,8 @@ export class LocalStoredShortcuts implements ShortcutApi { return pageTheme[theme].colors[0]; } - private subscribers = new Set< - ZenObservable.SubscriptionObserver - >(); - - private readonly observable = new ObservableImpl(subscriber => { - subscriber.next(this.get()); - this.subscribers.add(subscriber); - - return () => { - this.subscribers.delete(subscriber); - }; - }); - private readonly THEME_MAP: Record = { catalog: 'home', docs: 'documentation', }; - - private get() { - return Array.from( - this.storageApi.snapshot('items').value ?? [], - ).sort((a, b) => (a.title >= b.title ? 1 : -1)); - } - - private notify() { - for (const subscription of this.subscribers) { - subscription.next(this.get()); - } - } } diff --git a/plugins/shortcuts/src/api/ShortcutApi.ts b/plugins/shortcuts/src/api/ShortcutApi.ts index 893a2fd74b..1f93baa66c 100644 --- a/plugins/shortcuts/src/api/ShortcutApi.ts +++ b/plugins/shortcuts/src/api/ShortcutApi.ts @@ -28,6 +28,11 @@ export interface ShortcutApi { */ shortcut$(): Observable; + /** + * Returns an immediate snapshot of shortcuts, sorted by title + */ + get(): Shortcut[]; + /** * Generates a unique id for the shortcut and then saves it. */ diff --git a/plugins/sonarqube-backend/.eslintrc.js b/plugins/sonarqube-backend/.eslintrc.js new file mode 100644 index 0000000000..e2a53a6ad2 --- /dev/null +++ b/plugins/sonarqube-backend/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@backstage/cli/config/eslint-factory')(__dirname); diff --git a/plugins/sonarqube-backend/CHANGELOG.md b/plugins/sonarqube-backend/CHANGELOG.md new file mode 100644 index 0000000000..06b98d9044 --- /dev/null +++ b/plugins/sonarqube-backend/CHANGELOG.md @@ -0,0 +1,23 @@ +# @backstage/plugin-sonarqube-backend + +## 0.1.0 + +### Minor Changes + +- e2be9ab3a4: Initial creation of the plugin + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + +## 0.1.0-next.0 + +### Minor Changes + +- e2be9ab3a4: Initial creation of the plugin + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 diff --git a/plugins/sonarqube-backend/README.md b/plugins/sonarqube-backend/README.md new file mode 100644 index 0000000000..ac3973a5c0 --- /dev/null +++ b/plugins/sonarqube-backend/README.md @@ -0,0 +1,139 @@ +# sonarqube-backend + +Welcome to the sonarqube-backend backend plugin! + +## Integrating into a backstage instance + +This plugin needs to be added to an existing backstage instance. + +```bash +# From your Backstage root directory +yarn add --cwd packages/backend @backstage/plugin-sonarqube-backend +``` + +Typically, this means creating a `src/plugins/sonarqube.ts` file and adding a reference to it to `src/index.ts` in the backend package. + +### sonarqube.ts + +```typescript +import { + createRouter, + DefaultSonarqubeInfoProvider, +} from '@backstage/plugin-sonarqube-backend'; +import { Router } from 'express'; +import { PluginEnvironment } from '../types'; + +export default async function createPlugin( + env: PluginEnvironment, +): Promise { + return await createRouter({ + logger: env.logger, + sonarqubeInfoProvider: DefaultSonarqubeInfoProvider.fromConfig(env.config), + }); +} +``` + +### src/index.ts + +```diff +diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts +index 1942c36ad1..7fdc48ba24 100644 +--- a/packages/backend/src/index.ts ++++ b/packages/backend/src/index.ts +@@ -50,6 +50,7 @@ import scaffolder from './plugins/scaffolder'; + import proxy from './plugins/proxy'; + import search from './plugins/search'; + import techdocs from './plugins/techdocs'; ++import sonarqube from './plugins/sonarqube'; + import techInsights from './plugins/techInsights'; + import todo from './plugins/todo'; + import graphql from './plugins/graphql'; +@@ -133,6 +134,7 @@ async function main() { + createEnv('tech-insights'), + ); + const permissionEnv = useHotMemoize(module, () => createEnv('permission')); ++ const sonarqubeEnv = useHotMemoize(module, () => createEnv('sonarqube')); + + const apiRouter = Router(); + apiRouter.use('/catalog', await catalog(catalogEnv)); +@@ -152,6 +154,7 @@ async function main() { + apiRouter.use('/badges', await badges(badgesEnv)); + apiRouter.use('/jenkins', await jenkins(jenkinsEnv)); + apiRouter.use('/permission', await permission(permissionEnv)); ++ apiRouter.use('/sonarqube', await sonarqube(sonarqubeEnv)); + apiRouter.use(notFoundHandler()); + + const service = createServiceBuilder(module) + +``` + +This plugin must be provided with a `SonarqubeInfoProvider`, this is a strategy object for finding Sonarqube instances in configuration and retrieving data from an instance. + +There is a standard one provided (`DefaultSonarqubeInfoProvider`), but the Integrator is free to build their own. + +### DefaultSonarqubeInfoProvider + +Allows configuration of either a single or multiple global Sonarqube instances and annotating entities with the instance name. This instance name in the entities is optional, if not provided the default instance in configuration will be used. That allow to keep configuration from before multiple instances capability to keep working without changes. + +#### Example - Single global instance + +##### Config + +```yaml +sonarqube: + baseUrl: https://sonarqube.example.com + apiKey: 123456789abcdef0123456789abcedf012 +``` + +##### Catalog + +```yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage + annotations: + sonarqube.org/project-key: YOUR_INSTANCE_NAME/YOUR_PROJECT_KEY +``` + +#### Example - Multiple global instance + +The following will look for findings at `https://special-project-sonarqube.example.com` for the project of key `YOUR_PROJECT_KEY`. + +##### Config + +```yaml +sonarqube: + instances: + - name: default + baseUrl: https://default-sonarqube.example.com + apiKey: 123456789abcdef0123456789abcedf012 + - name: specialProject + baseUrl: https://special-project-sonarqube.example.com + apiKey: abcdef0123456789abcedf0123456789ab +``` + +##### Catalog + +```yaml +apiVersion: backstage.io/v1alpha1 +kind: Component +metadata: + name: backstage + annotations: + sonarqube.org/project-key: specialProject/YOUR_PROJECT_KEY +``` + +If the `specialProject/` part is omitted (or replaced with `default/`), the Sonarqube instance of name `default` will be used. + +The following config is an equivalent (but less clear) version of the above: + +```yaml +sonarqube: + baseUrl: https://default-sonarqube.example.com + apiKey: 123456789abcdef0123456789abcedf012 + instances: + - name: specialProject + baseUrl: https://special-project-sonarqube.example.com + apiKey: abcdef0123456789abcedf0123456789ab +``` diff --git a/plugins/sonarqube-backend/api-report.md b/plugins/sonarqube-backend/api-report.md new file mode 100644 index 0000000000..0fbd463cf3 --- /dev/null +++ b/plugins/sonarqube-backend/api-report.md @@ -0,0 +1,73 @@ +## API Report File for "@backstage/plugin-sonarqube-backend" + +> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/). + +```ts +import { Config } from '@backstage/config'; +import express from 'express'; +import { Logger } from 'winston'; + +// @public +export function createRouter(options: RouterOptions): Promise; + +// @public +export class DefaultSonarqubeInfoProvider implements SonarqubeInfoProvider { + static fromConfig(config: Config): DefaultSonarqubeInfoProvider; + getBaseUrl(options?: { instanceName?: string }): { + baseUrl: string; + }; + getFindings(options: { + componentKey: string; + instanceName?: string; + }): Promise; +} + +// @public +export interface RouterOptions { + logger: Logger; + sonarqubeInfoProvider: SonarqubeInfoProvider; +} + +// @public +export class SonarqubeConfig { + constructor(instances: SonarqubeInstanceConfig[]); + static fromConfig(config: Config): SonarqubeConfig; + getInstanceConfig(options?: { + sonarqubeName?: string; + }): SonarqubeInstanceConfig; + // (undocumented) + readonly instances: SonarqubeInstanceConfig[]; +} + +// @public +export interface SonarqubeFindings { + analysisDate: string; + measures: SonarqubeMeasure[]; +} + +// @public +export interface SonarqubeInfoProvider { + getBaseUrl(options?: { instanceName?: string }): { + baseUrl: string; + }; + getFindings(options: { + componentKey: string; + instanceName?: string; + }): Promise; +} + +// @public +export interface SonarqubeInstanceConfig { + apiKey: string; + baseUrl: string; + name: string; +} + +// @public +export interface SonarqubeMeasure { + metric: string; + value: string; +} + +// (No @packageDocumentation comment for this package) +``` diff --git a/plugins/sonarqube-backend/package.json b/plugins/sonarqube-backend/package.json new file mode 100644 index 0000000000..cdfdb005b5 --- /dev/null +++ b/plugins/sonarqube-backend/package.json @@ -0,0 +1,46 @@ +{ + "name": "@backstage/plugin-sonarqube-backend", + "version": "0.1.0", + "main": "src/index.ts", + "types": "src/index.ts", + "license": "Apache-2.0", + "private": false, + "publishConfig": { + "access": "public", + "main": "dist/index.cjs.js", + "types": "dist/index.d.ts" + }, + "backstage": { + "role": "backend-plugin" + }, + "scripts": { + "start": "backstage-cli package start", + "build": "backstage-cli package build", + "lint": "backstage-cli package lint", + "test": "backstage-cli package test", + "clean": "backstage-cli package clean", + "prepack": "backstage-cli package prepack", + "postpack": "backstage-cli package postpack" + }, + "dependencies": { + "@backstage/backend-common": "^0.15.0", + "@backstage/config": "^1.0.1", + "@backstage/errors": "^1.1.0", + "@types/express": "*", + "express": "^4.18.1", + "express-promise-router": "^4.1.0", + "node-fetch": "^2.6.7", + "winston": "^3.8.1", + "yn": "^5.0.0" + }, + "devDependencies": { + "@backstage/cli": "^0.18.1", + "@backstage/test-utils": "^1.1.3", + "@types/supertest": "^2.0.12", + "msw": "^0.45.0", + "supertest": "^6.2.4" + }, + "files": [ + "dist" + ] +} diff --git a/plugins/sonarqube-backend/src/index.ts b/plugins/sonarqube-backend/src/index.ts new file mode 100644 index 0000000000..c91aef09f8 --- /dev/null +++ b/plugins/sonarqube-backend/src/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export * from './service/router'; +export * from './service/sonarqubeInfoProvider'; diff --git a/plugins/sonarqube-backend/src/run.ts b/plugins/sonarqube-backend/src/run.ts new file mode 100644 index 0000000000..0a3ed2b7f0 --- /dev/null +++ b/plugins/sonarqube-backend/src/run.ts @@ -0,0 +1,33 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getRootLogger } from '@backstage/backend-common'; +import yn from 'yn'; +import { startStandaloneServer } from './service/standaloneServer'; + +const port = process.env.PLUGIN_PORT ? Number(process.env.PLUGIN_PORT) : 7007; +const enableCors = yn(process.env.PLUGIN_CORS, { default: false }); +const logger = getRootLogger(); + +startStandaloneServer({ port, enableCors, logger }).catch(err => { + logger.error(err); + process.exit(1); +}); + +process.on('SIGINT', () => { + logger.info('CTRL+C pressed; exiting.'); + process.exit(0); +}); diff --git a/plugins/sonarqube-backend/src/service/router.test.ts b/plugins/sonarqube-backend/src/service/router.test.ts new file mode 100644 index 0000000000..426066d897 --- /dev/null +++ b/plugins/sonarqube-backend/src/service/router.test.ts @@ -0,0 +1,145 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getVoidLogger } from '@backstage/backend-common'; +import express from 'express'; +import request from 'supertest'; + +import { createRouter } from './router'; +import { SonarqubeFindings } from './sonarqubeInfoProvider'; + +describe('createRouter', () => { + let app: express.Express; + const getBaseUrlMock: jest.Mock< + { baseUrl: string }, + [{ instanceName: string }] + > = jest.fn(); + const getFindingsMock: jest.Mock< + Promise, + [ + { + componentKey: string; + instanceName: string; + }, + ] + > = jest.fn(); + + beforeAll(async () => { + const router = await createRouter({ + logger: getVoidLogger(), + sonarqubeInfoProvider: { + getBaseUrl: getBaseUrlMock, + getFindings: getFindingsMock, + }, + }); + app = express().use(router); + }); + + beforeEach(() => { + jest.resetAllMocks(); + }); + + describe('GET /findings', () => { + const DUMMY_COMPONENT_KEY = 'my:component'; + const DUMMY_INSTANCE_KEY = 'myInstance'; + it('returns ok', async () => { + const measures = { + analysisDate: '2022-01-01T00:00:00Z', + measures: [{ metric: 'vulnerabilities', value: '54' }], + }; + + getFindingsMock.mockReturnValue(Promise.resolve(measures)); + const response = await request(app) + .get('/findings') + .query({ + componentKey: DUMMY_COMPONENT_KEY, + instanceKey: DUMMY_INSTANCE_KEY, + }) + .send(); + expect(getFindingsMock).toBeCalledTimes(1); + expect(getFindingsMock).toBeCalledWith({ + componentKey: DUMMY_COMPONENT_KEY, + instanceName: DUMMY_INSTANCE_KEY, + }); + expect(response.status).toEqual(200); + expect(response.body).toEqual(measures); + }); + it('returns an error when component key is not defined', async () => { + const response = await request(app) + .get('/findings') + .query({ + instanceKey: DUMMY_INSTANCE_KEY, + }) + .send(); + + expect(response.status).toEqual(400); + }); + + it('use the value as instance name when instance key not provided', async () => { + const measures = { + analysisDate: '2021-04-08', + measures: [{ metric: 'vulnerabilities', value: '54' }], + }; + + getFindingsMock.mockReturnValue(Promise.resolve(measures)); + const response = await request(app) + .get('/findings') + .query({ + componentKey: DUMMY_COMPONENT_KEY, + instanceKey: undefined, + }) + .send(); + + expect(getFindingsMock).toBeCalledTimes(1); + expect(getFindingsMock).toBeCalledWith({ + componentKey: DUMMY_COMPONENT_KEY, + instanceName: undefined, + }); + expect(response.status).toEqual(200); + expect(response.body).toEqual(measures); + }); + }); + describe('GET /instanceUrl', () => { + const DUMMY_INSTANCE_KEY = 'myInstance'; + const DUMMY_INSTANCE_URL = 'http://sonarqube.example.com'; + it('returns ok', async () => { + getBaseUrlMock.mockReturnValue({ baseUrl: DUMMY_INSTANCE_URL }); + const response = await request(app) + .get('/instanceUrl') + .query({ + instanceKey: DUMMY_INSTANCE_KEY, + }) + .send(); + expect(getBaseUrlMock).toBeCalledTimes(1); + expect(getBaseUrlMock).toBeCalledWith({ + instanceName: DUMMY_INSTANCE_KEY, + }); + expect(response.status).toEqual(200); + expect(response.body).toEqual({ instanceUrl: DUMMY_INSTANCE_URL }); + }); + + it('query default instance when instanceKey not provided', async () => { + getBaseUrlMock.mockReturnValue({ baseUrl: DUMMY_INSTANCE_URL }); + const response = await request(app).get('/instanceUrl').send(); + expect(getBaseUrlMock).toBeCalledTimes(1); + expect(getBaseUrlMock).toBeCalledWith({ + instanceName: undefined, + }); + expect(response.status).toEqual(200); + expect(response.body).toEqual({ instanceUrl: DUMMY_INSTANCE_URL }); + }); + }); +}); diff --git a/plugins/sonarqube-backend/src/service/router.ts b/plugins/sonarqube-backend/src/service/router.ts new file mode 100644 index 0000000000..f244ae5ce3 --- /dev/null +++ b/plugins/sonarqube-backend/src/service/router.ts @@ -0,0 +1,94 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { errorHandler } from '@backstage/backend-common'; +import express from 'express'; +import Router from 'express-promise-router'; +import { Logger } from 'winston'; +import { SonarqubeInfoProvider } from './sonarqubeInfoProvider'; +import { InputError } from '@backstage/errors'; + +/** + * Dependencies needed by the router + * @public + */ +export interface RouterOptions { + /** + * Logger for logging purposes + */ + logger: Logger; + /** + * Info provider to be able to get all necessary information for the APIs + */ + sonarqubeInfoProvider: SonarqubeInfoProvider; +} + +/** + * @public + * + * Constructs a sonarqube router. + * + * Expose endpoint to get information on or for a sonarqube instance. + * + * @param options - Dependencies of the router + */ +export async function createRouter( + options: RouterOptions, +): Promise { + const { logger, sonarqubeInfoProvider } = options; + + const router = Router(); + router.use(express.json()); + router.get('/findings', async (request, response) => { + const componentKey = request.query.componentKey as string; + const instanceKey = request.query.instanceKey as string; + + if (!componentKey) + throw new InputError('ComponentKey must be provided as a single string.'); + + logger.info( + instanceKey + ? `Retrieving findings for component ${componentKey} in sonarqube instance name ${instanceKey}` + : `Retrieving findings for component ${componentKey} in default sonarqube instance`, + ); + + response.json( + await sonarqubeInfoProvider.getFindings({ + componentKey, + instanceName: instanceKey, + }), + ); + }); + + router.get('/instanceUrl', (request, response) => { + const instanceKey = request.query.instanceKey as string; + + logger.info( + instanceKey + ? `Retrieving sonarqube instance URL for key ${instanceKey}` + : `Retrieving default sonarqube instance URL as instanceKey is not provided`, + ); + const { baseUrl } = sonarqubeInfoProvider.getBaseUrl({ + instanceName: instanceKey, + }); + response.json({ + instanceUrl: baseUrl, + }); + }); + + router.use(errorHandler()); + return router; +} diff --git a/plugins/sonarqube-backend/src/service/sonarqubeInfoProvider.test.ts b/plugins/sonarqube-backend/src/service/sonarqubeInfoProvider.test.ts new file mode 100644 index 0000000000..64313e8fd2 --- /dev/null +++ b/plugins/sonarqube-backend/src/service/sonarqubeInfoProvider.test.ts @@ -0,0 +1,541 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { ConfigReader } from '@backstage/config'; +import { + DefaultSonarqubeInfoProvider, + SonarqubeConfig, +} from './sonarqubeInfoProvider'; +import { setupServer } from 'msw/node'; +import { setupRequestMockHandlers } from '@backstage/test-utils'; +import { rest, RestRequest } from 'msw'; + +describe('SonarqubeConfig', () => { + const SONARQUBE_DEFAULT_INSTANCE_NAME = 'default'; + const DUMMY_SONAR_URL = 'https://sonarqube.example.com'; + const DUMMY_SONAR_APIKEY = '123456789abcdef0123456789abcedf012'; + const DUMMY_SIMPLE_OBJECT_FOR_DEFAULT_SONARQUBE_CONFIG = { + name: SONARQUBE_DEFAULT_INSTANCE_NAME, + baseUrl: DUMMY_SONAR_URL, + apiKey: DUMMY_SONAR_APIKEY, + }; + const DUMMY_SIMPLE_CONFIG = { + sonarqube: { + baseUrl: DUMMY_SONAR_URL, + apiKey: DUMMY_SONAR_APIKEY, + }, + }; + const DUMMY_NAMED_CONFIG = { + sonarqube: { + instances: [ + { + name: SONARQUBE_DEFAULT_INSTANCE_NAME, + baseUrl: DUMMY_SONAR_URL, + apiKey: DUMMY_SONAR_APIKEY, + }, + ], + }, + }; + + describe('fromConfig', () => { + it('Reads simple config and annotation', async () => { + const config = SonarqubeConfig.fromConfig( + new ConfigReader(DUMMY_SIMPLE_CONFIG), + ); + + expect(config.instances).toEqual([ + { + name: SONARQUBE_DEFAULT_INSTANCE_NAME, + baseUrl: DUMMY_SONAR_URL, + apiKey: DUMMY_SONAR_APIKEY, + }, + ]); + }); + + it('Reads named default config and annotation', async () => { + const config = SonarqubeConfig.fromConfig( + new ConfigReader(DUMMY_NAMED_CONFIG), + ); + + expect(config.instances).toEqual([ + { + name: SONARQUBE_DEFAULT_INSTANCE_NAME, + baseUrl: DUMMY_SONAR_URL, + apiKey: DUMMY_SONAR_APIKEY, + }, + ]); + }); + + it('Parses named default config (amongst named other configs)', async () => { + const config = SonarqubeConfig.fromConfig( + new ConfigReader({ + sonarqube: { + instances: [ + { + name: SONARQUBE_DEFAULT_INSTANCE_NAME, + baseUrl: DUMMY_SONAR_URL, + apiKey: DUMMY_SONAR_APIKEY, + }, + { + name: 'other', + baseUrl: 'https://sonarqube-other.example.com', + apiKey: 'abcdef0123456789abcedf0123456789abc', + }, + ], + }, + }), + ); + + expect(config.instances).toEqual([ + { + name: SONARQUBE_DEFAULT_INSTANCE_NAME, + baseUrl: DUMMY_SONAR_URL, + apiKey: DUMMY_SONAR_APIKEY, + }, + { + name: 'other', + baseUrl: 'https://sonarqube-other.example.com', + apiKey: 'abcdef0123456789abcedf0123456789abc', + }, + ]); + }); + it('Throw an error if both a named default config and top level config', async () => { + expect(() => + SonarqubeConfig.fromConfig( + new ConfigReader({ + sonarqube: { + baseUrl: DUMMY_SONAR_URL, + apiKey: DUMMY_SONAR_APIKEY, + instances: [ + { + name: SONARQUBE_DEFAULT_INSTANCE_NAME, + baseUrl: DUMMY_SONAR_URL, + apiKey: DUMMY_SONAR_APIKEY, + }, + ], + }, + }), + ), + ).toThrowError(Error); + }); + + it('Throw an error if default config is partially provided', async () => { + expect(() => + SonarqubeConfig.fromConfig( + new ConfigReader({ + sonarqube: { + baseUrl: DUMMY_SONAR_URL, + }, + }), + ), + ).toThrowError(Error); + }); + }); + + describe('getInstanceConfig', () => { + it('Gets default instance when no parameter given', async () => { + const config = new SonarqubeConfig([ + DUMMY_SIMPLE_OBJECT_FOR_DEFAULT_SONARQUBE_CONFIG, + { + name: 'other', + baseUrl: 'https://sonarqube-other.example.com', + apiKey: '123456789abcdef0123456789abcedf012', + }, + ]); + + expect(config.getInstanceConfig()).toEqual({ + name: SONARQUBE_DEFAULT_INSTANCE_NAME, + baseUrl: DUMMY_SONAR_URL, + apiKey: DUMMY_SONAR_APIKEY, + }); + }); + + it('Gets default instance when "default" given', async () => { + const config = new SonarqubeConfig([ + DUMMY_SIMPLE_OBJECT_FOR_DEFAULT_SONARQUBE_CONFIG, + { + name: 'other', + baseUrl: 'https://sonarqube-other.example.com', + apiKey: 'abcdef0123456789abcedf0123456789abc', + }, + ]); + + expect(config.getInstanceConfig({ sonarqubeName: 'default' })).toEqual({ + name: 'default', + baseUrl: 'https://sonarqube.example.com', + apiKey: '123456789abcdef0123456789abcedf012', + }); + }); + + it('Gets named instance', async () => { + const config = new SonarqubeConfig([ + DUMMY_SIMPLE_OBJECT_FOR_DEFAULT_SONARQUBE_CONFIG, + { + name: 'other', + baseUrl: 'https://sonarqube-other.example.com', + apiKey: '123456789abcdef0123456789abcedf012', + }, + ]); + + expect(config.getInstanceConfig({ sonarqubeName: 'other' })).toEqual({ + name: 'other', + baseUrl: 'https://sonarqube-other.example.com', + apiKey: '123456789abcdef0123456789abcedf012', + }); + }); + + it('Throw an error if default instance could not be found', async () => { + const config = new SonarqubeConfig([ + { + name: 'other', + baseUrl: 'https://sonarqube-other.example.com', + apiKey: '123456789abcdef0123456789abcedf012', + }, + ]); + + expect(() => + config.getInstanceConfig({ sonarqubeName: 'default' }), + ).toThrowError(Error); + }); + + it('Throw an error if named instance could not be found', async () => { + const config = new SonarqubeConfig([ + DUMMY_SIMPLE_OBJECT_FOR_DEFAULT_SONARQUBE_CONFIG, + ]); + + expect(() => + config.getInstanceConfig({ sonarqubeName: 'other' }), + ).toThrowError(Error); + }); + }); +}); + +const server = setupServer(); + +describe('DefaultSonarqubeInfoProvider', () => { + function configureProvider(configData: any) { + const config = new ConfigReader(configData); + + return DefaultSonarqubeInfoProvider.fromConfig(config); + } + + describe('getBaseUrl', () => { + it('Provide base url for default from simple config and non provided instanceName', async () => { + const provider = configureProvider({ + sonarqube: { + baseUrl: 'https://sonarqube.example.com', + apiKey: '123456789abcdef0123456789abcedf012', + }, + }); + + expect(provider.getBaseUrl()).toEqual({ + baseUrl: 'https://sonarqube.example.com', + }); + }); + + it('Provide base url for default from simple config and empty string', async () => { + const provider = configureProvider({ + sonarqube: { + baseUrl: 'https://sonarqube.example.com', + apiKey: '123456789abcdef0123456789abcedf012', + }, + }); + + expect(provider.getBaseUrl({ instanceName: '' })).toEqual({ + baseUrl: 'https://sonarqube.example.com', + }); + }); + + it('Provide base url for named default config and "default" string', async () => { + const provider = configureProvider({ + sonarqube: { + instances: [ + { + name: 'default', + baseUrl: 'https://sonarqube.example.com', + apiKey: '123456789abcdef0123456789abcedf012', + }, + ], + }, + }); + + expect(provider.getBaseUrl({ instanceName: 'default' })).toEqual({ + baseUrl: 'https://sonarqube.example.com', + }); + }); + + it('Provide base url for named config', async () => { + const provider = configureProvider({ + sonarqube: { + instances: [ + { + name: 'default', + baseUrl: 'https://sonarqube.example.com', + apiKey: '123456789abcdef0123456789abcedf012', + }, + { + name: 'other', + baseUrl: 'https://sonarqube-other.example.com', + apiKey: '123456789abcdef0123456789abcedf012', + }, + ], + }, + }); + + expect(provider.getBaseUrl({ instanceName: 'other' })).toEqual({ + baseUrl: 'https://sonarqube-other.example.com', + }); + }); + }); + + describe('getFindings', () => { + setupRequestMockHandlers(server); + const MOCK_BASE_URL = 'http://backstage:9191'; + const DUMMY_COMPONENT_KEY = 'dummyComponentKey'; + const DUMMY_ANALYSIS_DATE = '2022-01-01T00:00:00Z'; + const DUMMY_API_KEY = '123456789abcdef0123456789abcedf012'; + + const checkBasicAuthToken = (req: RestRequest) => { + if (req.headers && req.headers.has('Authorization')) { + expect(req.headers.get('Authorization')).toEqual( + `Basic MTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2VkZjAxMjo=`, + ); + } else { + throw new Error('Basic auth token not provided'); + } + }; + + const setupComponentHandler = () => { + server.use( + rest.get(`${MOCK_BASE_URL}/api/components/show`, (req, res, ctx) => { + checkBasicAuthToken(req); + expect(req.url.searchParams.toString()).toBe( + `component=${DUMMY_COMPONENT_KEY}`, + ); + return res( + ctx.json({ + component: { analysisDate: DUMMY_ANALYSIS_DATE }, + }), + ); + }), + ); + }; + const setupMetricsHandler = () => { + server.use( + rest.get(`${MOCK_BASE_URL}/api/metrics/search`, (req, res, ctx) => { + checkBasicAuthToken(req); + return res( + ctx.json({ + total: 4, + metrics: [ + { key: 'coverage' }, + { key: 'code_smells' }, + { key: 'vulnerabilities' }, + { key: 'unused_metric' }, + ], + }), + ); + }), + ); + }; + const setupMeasureHandler = () => { + server.use( + rest.get(`${MOCK_BASE_URL}/api/measures/component`, (req, res, ctx) => { + checkBasicAuthToken(req); + expect(req.url.searchParams.toString()).toBe( + `component=${DUMMY_COMPONENT_KEY}&metricKeys=vulnerabilities%2Ccode_smells%2Ccoverage`, + ); + return res( + ctx.json({ + component: { + measures: [ + { metric: 'coverage', value: '86' }, + { metric: 'code_smells', value: '40' }, + { metric: 'vulnerabilities', value: '3' }, + ], + }, + }), + ); + }), + ); + }; + + const setupHandlers = () => { + setupComponentHandler(); + setupMetricsHandler(); + setupMeasureHandler(); + }; + + const DUMMY_SIMPLE_CONFIG_FOR_PROVIDER = { + sonarqube: { + baseUrl: MOCK_BASE_URL, + apiKey: DUMMY_API_KEY, + }, + }; + it('Provide findings when everything is ok', async () => { + setupHandlers(); + const provider = configureProvider(DUMMY_SIMPLE_CONFIG_FOR_PROVIDER); + expect( + await provider.getFindings({ + componentKey: DUMMY_COMPONENT_KEY, + instanceName: 'default', + }), + ).toEqual({ + analysisDate: DUMMY_ANALYSIS_DATE, + measures: [ + { metric: 'coverage', value: '86' }, + { metric: 'code_smells', value: '40' }, + { metric: 'vulnerabilities', value: '3' }, + ], + }); + }); + + it('Provide undefined as finding if component API answer code is not 200', async () => { + server.use( + rest.get(`${MOCK_BASE_URL}/api/components/show`, (req, res, ctx) => { + checkBasicAuthToken(req); + expect(req.url.searchParams.toString()).toBe( + `component=${DUMMY_COMPONENT_KEY}`, + ); + return res(ctx.status(500)); + }), + ); + + const provider = configureProvider({ + sonarqube: { + baseUrl: MOCK_BASE_URL, + apiKey: '123456789abcdef0123456789abcedf012', + }, + }); + expect( + await provider.getFindings({ + componentKey: DUMMY_COMPONENT_KEY, + instanceName: 'default', + }), + ).toBeUndefined(); + }); + it('Provide undefined as finding if component API answer incorrectly', async () => { + server.use( + rest.get(`${MOCK_BASE_URL}/api/components/show`, (req, res, ctx) => { + checkBasicAuthToken(req); + expect(req.url.searchParams.toString()).toBe( + `component=${DUMMY_COMPONENT_KEY}`, + ); + return res( + ctx.json({ + invalid: true, + }), + ); + }), + ); + + const provider = configureProvider(DUMMY_SIMPLE_CONFIG_FOR_PROVIDER); + expect( + await provider.getFindings({ + componentKey: DUMMY_COMPONENT_KEY, + instanceName: 'default', + }), + ).toBeUndefined(); + }); + it('Provide findings when metrics API uses pages', async () => { + setupComponentHandler(); + setupMeasureHandler(); + // custom metrics handler that provide two pages + server.use( + rest.get(`${MOCK_BASE_URL}/api/metrics/search`, (req, res, ctx) => { + checkBasicAuthToken(req); + if (req.url.searchParams.get('p') === '1') + return res( + ctx.json({ + total: 4, + metrics: [{ key: 'coverage' }, { key: 'code_smells' }], + }), + ); + return res( + ctx.json({ + total: 4, + metrics: [{ key: 'vulnerabilities' }, { key: 'unused_metric' }], + }), + ); + }), + ); + + const provider = configureProvider(DUMMY_SIMPLE_CONFIG_FOR_PROVIDER); + expect( + await provider.getFindings({ + componentKey: DUMMY_COMPONENT_KEY, + instanceName: 'default', + }), + ).toEqual({ + analysisDate: DUMMY_ANALYSIS_DATE, + measures: [ + { metric: 'coverage', value: '86' }, + { metric: 'code_smells', value: '40' }, + { metric: 'vulnerabilities', value: '3' }, + ], + }); + }); + + it('Provide undefined as findings when measure API answer code is not 200', async () => { + setupComponentHandler(); + setupMetricsHandler(); + // custom metrics handler that provide two pages + server.use( + rest.get(`${MOCK_BASE_URL}/api/measures/component`, (req, res, ctx) => { + checkBasicAuthToken(req); + expect(req.url.searchParams.toString()).toBe( + `component=${DUMMY_COMPONENT_KEY}&metricKeys=vulnerabilities%2Ccode_smells%2Ccoverage`, + ); + return res(ctx.status(500)); + }), + ); + + const provider = configureProvider(DUMMY_SIMPLE_CONFIG_FOR_PROVIDER); + expect( + await provider.getFindings({ + componentKey: DUMMY_COMPONENT_KEY, + instanceName: 'default', + }), + ).toBeUndefined(); + }); + + it('Provide findings with empty measures when metrics API answer incorrectly', async () => { + setupComponentHandler(); + setupMetricsHandler(); + // custom metrics handler that provide two pages + server.use( + rest.get(`${MOCK_BASE_URL}/api/measures/component`, (req, res, ctx) => { + checkBasicAuthToken(req); + expect(req.url.searchParams.toString()).toBe( + `component=${DUMMY_COMPONENT_KEY}&metricKeys=vulnerabilities%2Ccode_smells%2Ccoverage`, + ); + return res(ctx.json({})); + }), + ); + + const provider = configureProvider(DUMMY_SIMPLE_CONFIG_FOR_PROVIDER); + expect( + await provider.getFindings({ + componentKey: DUMMY_COMPONENT_KEY, + instanceName: 'default', + }), + ).toEqual({ + analysisDate: DUMMY_ANALYSIS_DATE, + measures: [], + }); + }); + }); +}); diff --git a/plugins/sonarqube-backend/src/service/sonarqubeInfoProvider.ts b/plugins/sonarqube-backend/src/service/sonarqubeInfoProvider.ts new file mode 100644 index 0000000000..2b96e6764e --- /dev/null +++ b/plugins/sonarqube-backend/src/service/sonarqubeInfoProvider.ts @@ -0,0 +1,382 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Config } from '@backstage/config'; +import fetch from 'node-fetch'; + +/** + * Provide information about sonarqube instances and projects contained within + * @public + */ +export interface SonarqubeInfoProvider { + /** + * Get the sonarqube URL in configuration from a provided instanceName. + * + * If instanceName is omitted, default sonarqube instance is queried in config + * + * @param instanceName - Name of the sonarqube instance to get the info from + * @returns the url of the instance + */ + getBaseUrl(options?: { instanceName?: string }): { baseUrl: string }; + + /** + * Query the sonarqube instance corresponding to the instanceName to get all + * measures for the component of key componentKey. + * + * If instanceName is omitted, default sonarqube instance is queried in config + * + * @param componentKey - component key of the project we want to get measure from. + * @param instanceName - name of the instance (in config) where the project is hosted. + * @returns All measures with the analysis date. Will return undefined if we + * can't provide the full response + */ + getFindings(options: { + componentKey: string; + instanceName?: string; + }): Promise; +} + +/** + * Information retrieved for a specific project in Sonarqube + * @public + */ +export interface SonarqubeFindings { + /** + * Last date of the analysis that have generated this finding + */ + analysisDate: string; + /** + * All measures pertaining to the findings + */ + measures: SonarqubeMeasure[]; +} + +interface MeasuresWrapper { + component: { measures: SonarqubeMeasure[] }; +} + +/** + * A specific measure on a project in Sonarqube + * @public + */ +export interface SonarqubeMeasure { + /** + * Name of the measure + */ + metric: string; + /** + * Value of the measure + */ + value: string; +} + +/** + * Information about a Sonarqube instance. + * @public + */ +export interface SonarqubeInstanceConfig { + /** + * Name of the instance. An instance name in configuration and catalog should match. + */ + name: string; + /** + * Base url to access the instance + */ + baseUrl: string; + /** + * Access token to access the sonarqube instance as generated in user profile. + */ + apiKey: string; +} + +interface ComponentWrapper { + component: { analysisDate: string }; +} + +/** + * Holds multiple Sonarqube configurations. + * @public + */ +export class SonarqubeConfig { + /** + * + * @param instances - All information on all sonarqube instance from the config file + */ + constructor(public readonly instances: SonarqubeInstanceConfig[]) {} + + /** + * Read all Sonarqube instance configurations. + * @param config - Root configuration + * @returns A SonarqubeConfig that contains all configured Sonarqube instances. + */ + static fromConfig(config: Config): SonarqubeConfig { + const DEFAULT_SONARQUBE_NAME = 'default'; + + const sonarqubeConfig = config.getConfig('sonarqube'); + + // load all named instance config + const namedInstanceConfig = + sonarqubeConfig.getOptionalConfigArray('instances')?.map(c => ({ + name: c.getString('name'), + baseUrl: c.getString('baseUrl'), + apiKey: c.getString('apiKey'), + })) || []; + + // load unnamed default config + const hasNamedDefault = namedInstanceConfig.some( + x => x.name === DEFAULT_SONARQUBE_NAME, + ); + + // Get these as optional strings and check to give a better error message + const baseUrl = sonarqubeConfig.getOptionalString('baseUrl'); + const apiKey = sonarqubeConfig.getOptionalString('apiKey'); + + if (hasNamedDefault && (baseUrl || apiKey)) { + throw new Error( + `Found both a named sonarqube instance with name ${DEFAULT_SONARQUBE_NAME} and top level baseUrl or apiKey config. Use only one style of config.`, + ); + } + + const unnamedNonePresent = !baseUrl && !apiKey; + const unnamedAllPresent = baseUrl && apiKey; + if (!(unnamedAllPresent || unnamedNonePresent)) { + throw new Error( + `Found partial default sonarqube config. All (or none) of baseUrl and apiKey must be provided.`, + ); + } + + if (unnamedAllPresent) { + const unnamedInstanceConfig = [ + { name: DEFAULT_SONARQUBE_NAME, baseUrl, apiKey }, + ] as { + name: string; + baseUrl: string; + apiKey: string; + }[]; + + return new SonarqubeConfig([ + ...namedInstanceConfig, + ...unnamedInstanceConfig, + ]); + } + + return new SonarqubeConfig(namedInstanceConfig); + } + + /** + * Gets a Sonarqube instance configuration by name, or the default one if no name is provided. + * @param sonarqubeName - Optional name of the Sonarqube instance. + * @returns The requested Sonarqube instance. + * @throws Error when no default config could be found or the requested name couldn't be found in config. + */ + getInstanceConfig( + options: { sonarqubeName?: string } = {}, + ): SonarqubeInstanceConfig { + const { sonarqubeName } = options; + const DEFAULT_SONARQUBE_NAME = 'default'; + + if (!sonarqubeName || sonarqubeName === DEFAULT_SONARQUBE_NAME) { + // no name provided, use default + const instanceConfig = this.instances.find( + c => c.name === DEFAULT_SONARQUBE_NAME, + ); + + if (!instanceConfig) { + throw new Error( + `Couldn't find a default sonarqube instance in the config. Either configure an instance with name ${DEFAULT_SONARQUBE_NAME} or add a prefix to your annotation value.`, + ); + } + + return instanceConfig; + } + + // A name is provided, look it up. + const instanceConfig = this.instances.find(c => c.name === sonarqubeName); + + if (!instanceConfig) { + throw new Error( + `Couldn't find a sonarqube instance in the config with name ${sonarqubeName}`, + ); + } + return instanceConfig; + } +} + +/** + * @public + * + * Use default config and annotations, build using fromConfig static function. + */ +export class DefaultSonarqubeInfoProvider implements SonarqubeInfoProvider { + private constructor(private readonly config: SonarqubeConfig) {} + + /** + * Generate an instance from a Config instance + * @param config - Backend configuration + */ + static fromConfig(config: Config): DefaultSonarqubeInfoProvider { + return new DefaultSonarqubeInfoProvider(SonarqubeConfig.fromConfig(config)); + } + + /** + * Retrieve all supported metrics from a sonarqube instance. + * + * @param instanceUrl - URL of the sonarqube instance + * @param token - token to access the sonarqube instance + * @returns The list of supported metrics, if no metrics are supported an empty list is provided in the promise + * @private + */ + private static async getSupportedMetrics( + instanceUrl: string, + token: string, + ): Promise { + const metrics: string[] = []; + let nextPage: number = 1; + + for (;;) { + const result = await DefaultSonarqubeInfoProvider.callApi<{ + metrics: Array<{ key: string }>; + total: number; + }>(instanceUrl, 'api/metrics/search', token, { ps: 500, p: nextPage }); + metrics.push(...(result?.metrics?.map(m => m.key) ?? [])); + + if (result && metrics.length < result.total) { + nextPage++; + continue; + } + + return metrics; + } + } + + /** + * Call an API with provided arguments + * @param url - URL of the API to call + * @param path - path to call + * @param authToken - token used as basic auth user without password + * @param query - parameters to provide to the call + * @returns A promise on the answer to the API call if the answer status code is 200, undefined otherwise. + * @private + */ + private static async callApi( + url: string, + path: string, + authToken: string, + query: { [key in string]: any }, + ): Promise { + // Sonarqube auth use basic with token as username and no password + // but standard dictate the colon (separator) need to stay here despite the + // lack of password + const encodedAuthToken = Buffer.from(`${authToken}:`).toString('base64'); + + const response = await fetch( + `${url}/${path}?${new URLSearchParams(query).toString()}`, + { + headers: { + 'Content-Type': 'application/json', + Authorization: `Basic ${encodedAuthToken}`, + }, + }, + ); + if (response.status === 200) { + return (await response.json()) as T; + } + return undefined; + } + + /** + * {@inheritDoc SonarqubeInfoProvider.getBaseUrl} + * @throws Error If configuration can't be retrieved. + */ + getBaseUrl(options: { instanceName?: string } = {}): { + baseUrl: string; + } { + const instanceConfig = this.config.getInstanceConfig({ + sonarqubeName: options.instanceName, + }); + return { baseUrl: instanceConfig.baseUrl }; + } + + /** + * {@inheritDoc SonarqubeInfoProvider.getFindings} + * @throws Error If configuration can't be retrieved. + */ + async getFindings(options: { + componentKey: string; + instanceName?: string; + }): Promise { + const { componentKey, instanceName } = options; + const { baseUrl, apiKey } = this.config.getInstanceConfig({ + sonarqubeName: instanceName, + }); + + // get component info to retrieve analysis date + const component = + await DefaultSonarqubeInfoProvider.callApi( + baseUrl, + 'api/components/show', + apiKey, + { + component: componentKey, + }, + ); + if (!component || !component.component) { + return undefined; + } + + // select the metrics that are supported by the SonarQube instance + const supportedMetrics = + await DefaultSonarqubeInfoProvider.getSupportedMetrics(baseUrl, apiKey); + const wantedMetrics: string[] = [ + 'alert_status', + 'bugs', + 'reliability_rating', + 'vulnerabilities', + 'security_rating', + 'security_hotspots_reviewed', + 'security_review_rating', + 'code_smells', + 'sqale_rating', + 'coverage', + 'duplicated_lines_density', + ]; + + // only retrieve wanted metrics that are supported + const metricsToQuery = wantedMetrics.filter(el => + supportedMetrics.includes(el), + ); + + // get all measures + const measures = + await DefaultSonarqubeInfoProvider.callApi( + baseUrl, + 'api/measures/component', + apiKey, + { + component: componentKey, + metricKeys: metricsToQuery.join(','), + }, + ); + if (!measures) { + return undefined; + } + + return { + analysisDate: component.component.analysisDate, + measures: measures.component?.measures ?? [], + }; + } +} diff --git a/plugins/sonarqube-backend/src/service/standaloneServer.ts b/plugins/sonarqube-backend/src/service/standaloneServer.ts new file mode 100644 index 0000000000..06a8d4ffb2 --- /dev/null +++ b/plugins/sonarqube-backend/src/service/standaloneServer.ts @@ -0,0 +1,56 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + createServiceBuilder, + loadBackendConfig, +} from '@backstage/backend-common'; +import { Server } from 'http'; +import { Logger } from 'winston'; +import { createRouter } from './router'; +import { DefaultSonarqubeInfoProvider } from './sonarqubeInfoProvider'; + +export interface ServerOptions { + port: number; + enableCors: boolean; + logger: Logger; +} + +export async function startStandaloneServer( + options: ServerOptions, +): Promise { + const logger = options.logger.child({ service: 'sonarqube-backend-backend' }); + logger.debug('Starting application server...'); + const config = await loadBackendConfig({ logger, argv: process.argv }); + const router = await createRouter({ + logger, + sonarqubeInfoProvider: DefaultSonarqubeInfoProvider.fromConfig(config), + }); + + let service = createServiceBuilder(module) + .setPort(options.port) + .addRouter('/sonarqube', router); + if (options.enableCors) { + service = service.enableCors({ origin: 'http://localhost:3000' }); + } + + return await service.start().catch(err => { + logger.error(err); + process.exit(1); + }); +} + +module.hot?.accept(); diff --git a/plugins/sonarqube-backend/src/setupTests.ts b/plugins/sonarqube-backend/src/setupTests.ts new file mode 100644 index 0000000000..d3232290a7 --- /dev/null +++ b/plugins/sonarqube-backend/src/setupTests.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export {}; diff --git a/plugins/sonarqube/CHANGELOG.md b/plugins/sonarqube/CHANGELOG.md index 0d6ef3a2b1..9181ae3fcf 100644 --- a/plugins/sonarqube/CHANGELOG.md +++ b/plugins/sonarqube/CHANGELOG.md @@ -1,5 +1,71 @@ # @backstage/plugin-sonarqube +## 0.4.0 + +### Minor Changes + +- 619b515172: **BREAKING** This plugin now call the `sonarqube-backend` plugin instead of relying on the proxy plugin + + The whole proxy's `'/sonarqube':` key can be removed from your configuration files. + + Then head to the [README in sonarqube-backend plugin page](https://github.com/backstage/backstage/tree/master/plugins/sonarqube-backend/README.md) to learn how to set-up the link to your Sonarqube instances. + +### Patch Changes + +- f9c310a439: Add ability to provide an optional Sonarqube instance into the annotation in the `catalog-info.yaml` file +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.4.0-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.4.0-next.1 + +### Minor Changes + +- 619b515172: **BREAKING** This plugin now call the `sonarqube-backend` plugin instead of relying on the proxy plugin + + The whole proxy's `'/sonarqube':` key can be removed from your configuration files. + + Then head to the [README in sonarqube-backend plugin page](https://github.com/backstage/backstage/tree/master/plugins/sonarqube-backend/README.md) to learn how to set-up the link to your Sonarqube instances. + +### Patch Changes + +- f9c310a439: Add ability to provide an optional Sonarqube instance into the annotation in the `catalog-info.yaml` file +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## 0.3.8-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.3.7 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 15201b1032: Updated dependency `rc-progress` to `3.4.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.3.7-next.3 ### Patch Changes diff --git a/plugins/sonarqube/README.md b/plugins/sonarqube/README.md index febce4ecfc..d8ed6dfb8d 100644 --- a/plugins/sonarqube/README.md +++ b/plugins/sonarqube/README.md @@ -33,50 +33,14 @@ yarn add --cwd packages/app @backstage/plugin-sonarqube ); ``` -3. Add the proxy config: - - Provide a method for your Backstage backend to get to your SonarQube API end point. Add configuration to your `app-config.yaml` file depending on the product you use. Make sure to keep the trailing colon after the `SONARQUBE_TOKEN`, it is required to call - the Web API (see [docs](https://docs.sonarqube.org/latest/extend/web-api/)). - -**SonarCloud** - -```yaml -proxy: - '/sonarqube': - target: https://sonarcloud.io/api - allowedMethods: ['GET'] - # note that the colon after the token is required - auth: '${SONARQUBE_TOKEN}:' - # Environmental variable: SONARQUBE_TOKEN - # Fetch the sonar-auth-token from https://sonarcloud.io/account/security/ -``` - -**SonarQube** - -```yaml -proxy: - '/sonarqube': - target: https://your.sonarqube.instance.com/api - allowedMethods: ['GET'] - # note that the colon after the token is required - auth: '${SONARQUBE_TOKEN}:' - # Environmental variable: SONARQUBE_TOKEN - # Fetch the sonar-auth-token from https://sonarcloud.io/account/security/ - -sonarQube: - baseUrl: https://your.sonarqube.instance.com -``` - -4. Get and provide `SONARQUBE_TOKEN` as an env variable (https://sonarcloud.io/account/security or https://docs.sonarqube.org/latest/user-guide/user-token/). - -5. Run the following commands in the root folder of the project to install and compile the changes. +3. Run the following commands in the root folder of the project to install and compile the changes. ```yaml yarn install yarn tsc ``` -6. Add the `sonarqube.org/project-key` annotation to the `catalog-info.yaml` file of the target repo for which code quality analysis is needed. +4. Add the `sonarqube.org/project-key` annotation to the `catalog-info.yaml` file of the target repo for which code quality analysis is needed. ```yaml apiVersion: backstage.io/v1alpha1 @@ -86,9 +50,11 @@ metadata: description: | Backstage is an open-source developer portal that puts the developer experience first. annotations: - sonarqube.org/project-key: YOUR_PROJECT_KEY + sonarqube.org/project-key: YOUR_INSTANCE_NAME/YOUR_PROJECT_KEY spec: type: library owner: CNCF lifecycle: experimental ``` + +`YOUR_INSTANCE_NAME/` is optional and will query the default instance if not provided. diff --git a/plugins/sonarqube/api-report.md b/plugins/sonarqube/api-report.md index a7549a689c..e0a51479a4 100644 --- a/plugins/sonarqube/api-report.md +++ b/plugins/sonarqube/api-report.md @@ -9,46 +9,29 @@ import { BackstagePlugin } from '@backstage/core-plugin-api'; import { Entity } from '@backstage/catalog-model'; import { InfoCardVariants } from '@backstage/core-components'; -// Warning: (ae-missing-release-tag) "EntitySonarQubeCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const EntitySonarQubeCard: ({ - variant, - duplicationRatings, -}: { - variant?: InfoCardVariants | undefined; - duplicationRatings?: - | { - greaterThan: number; - rating: '1.0' | '2.0' | '3.0' | '4.0' | '5.0'; - }[] - | undefined; -}) => JSX.Element; +export type DuplicationRating = { + greaterThan: number; + rating: '1.0' | '2.0' | '3.0' | '4.0' | '5.0'; +}; -// Warning: (ae-missing-release-tag) "isSonarQubeAvailable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const isSonarQubeAvailable: (entity: Entity) => boolean; - -// Warning: (ae-missing-release-tag) "SonarQubeCard" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export const SonarQubeCard: ({ - variant, - duplicationRatings, -}: { +export const EntitySonarQubeCard: (props: { variant?: InfoCardVariants | undefined; duplicationRatings?: DuplicationRating[] | undefined; }) => JSX.Element; -// Warning: (ae-missing-release-tag) "sonarQubePlugin" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -const sonarQubePlugin: BackstagePlugin<{}, {}>; +export const isSonarQubeAvailable: (entity: Entity) => boolean; + +// @public (undocumented) +export const SonarQubeCard: (props: { + variant?: InfoCardVariants; + duplicationRatings?: DuplicationRating[]; +}) => JSX.Element; + +// @public (undocumented) +const sonarQubePlugin: BackstagePlugin<{}, {}, {}>; export { sonarQubePlugin as plugin }; export { sonarQubePlugin }; - -// Warnings were encountered during analysis: -// -// src/components/SonarQubeCard/SonarQubeCard.d.ts:9:5 - (ae-forgotten-export) The symbol "DuplicationRating" needs to be exported by the entry point index.d.ts ``` diff --git a/plugins/sonarqube/package.json b/plugins/sonarqube/package.json index 5d14b6d017..ac3a8302b0 100644 --- a/plugins/sonarqube/package.json +++ b/plugins/sonarqube/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-sonarqube", "description": "", - "version": "0.3.7-next.3", + "version": "0.4.0", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -36,11 +36,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -53,16 +53,16 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/sonarqube/src/api/SonarQubeApi.ts b/plugins/sonarqube/src/api/SonarQubeApi.ts index 3b39b30eb0..9dbb6331dd 100644 --- a/plugins/sonarqube/src/api/SonarQubeApi.ts +++ b/plugins/sonarqube/src/api/SonarQubeApi.ts @@ -38,5 +38,8 @@ export const sonarQubeApiRef = createApiRef({ }); export type SonarQubeApi = { - getFindingSummary(componentKey?: string): Promise; + getFindingSummary(options: { + componentKey?: string; + projectInstance?: string; + }): Promise; }; diff --git a/plugins/sonarqube/src/api/SonarQubeClient.test.ts b/plugins/sonarqube/src/api/SonarQubeClient.test.ts index b592953434..dc5d7f077e 100644 --- a/plugins/sonarqube/src/api/SonarQubeClient.test.ts +++ b/plugins/sonarqube/src/api/SonarQubeClient.test.ts @@ -18,7 +18,7 @@ import { setupRequestMockHandlers } from '@backstage/test-utils'; import { rest } from 'msw'; import { setupServer } from 'msw/node'; import { FindingSummary, SonarQubeClient } from './index'; -import { ComponentWrapper, MeasuresWrapper } from './types'; +import { InstanceUrlWrapper, FindingsWrapper } from './types'; import { UrlPatternDiscovery } from '@backstage/core-app-api'; import { IdentityApi } from '@backstage/core-plugin-api'; @@ -40,133 +40,77 @@ const identityApiGuest: IdentityApi = { describe('SonarQubeClient', () => { setupRequestMockHandlers(server); - const mockBaseUrl = 'http://backstage:9191/api/proxy'; + const mockBaseUrl = 'http://backstage:9191/api/sonarqube'; const discoveryApi = UrlPatternDiscovery.compile(mockBaseUrl); - const setupHandlers = ( - metricKeys = [ - 'alert_status', - 'bugs', - 'reliability_rating', - 'vulnerabilities', - 'security_rating', - 'security_hotspots_reviewed', - 'security_review_rating', - 'code_smells', - 'sqale_rating', - 'coverage', - 'duplicated_lines_density', - ], - ) => { + const setupHandlers = () => { server.use( - rest.get(`${mockBaseUrl}/sonarqube/metrics/search`, (req, res, ctx) => { - expect(req.url.searchParams.get('ps')).toBe('500'); - - // emulate paging to check if everything is requested - if (req.url.searchParams.get('p') === '1') { - return res( - ctx.json({ - metrics: metricKeys.slice(0, 5).map(k => ({ key: k })), - total: metricKeys.length, - }), - ); - } - - // make sure this is only called twice - expect(req.url.searchParams.get('p')).toBe('2'); - return res( - ctx.json({ - metrics: metricKeys.slice(5).map(k => ({ key: k })), - total: metricKeys.length, - }), - ); - }), - ); - - server.use( - rest.get(`${mockBaseUrl}/sonarqube/components/show`, (req, res, ctx) => { - expect(req.url.searchParams.toString()).toBe('component=our%3Aservice'); - return res( - ctx.json({ - component: { - analysisDate: '2020-01-01T00:00:00Z', - }, - } as ComponentWrapper), - ); - }), - ); - - server.use( - rest.get(`${mockBaseUrl}/sonarqube/measures/search`, (req, res, ctx) => { + rest.get(`${mockBaseUrl}/findings`, (req, res, ctx) => { expect(req.url.searchParams.toString()).toBe( - `projectKeys=our%3Aservice&metricKeys=${metricKeys.join('%2C')}`, + 'componentKey=our%3Aservice&instanceKey=', ); return res( ctx.json({ + analysisDate: '2020-01-01T00:00:00Z', measures: [ { metric: 'alert_status', value: 'OK', - component: 'our:service', - }, - { - metric: 'alert_status', - value: 'ERROR', - component: 'other-service', }, { metric: 'bugs', value: '2', - component: 'our:service', }, { metric: 'reliability_rating', value: '3.0', - component: 'our:service', }, { metric: 'vulnerabilities', value: '4', - component: 'our:service', }, { metric: 'security_rating', value: '1.0', - component: 'our:service', }, { metric: 'security_hotspots_reviewed', value: '100', - component: 'our:service', }, { metric: 'security_review_rating', value: '1.0', - component: 'our:service', }, { metric: 'code_smells', value: '100', - component: 'our:service', }, { metric: 'sqale_rating', value: '2.0', - component: 'our:service', }, { metric: 'coverage', value: '55.5', - component: 'our:service', }, { metric: 'duplicated_lines_density', value: '1.0', - component: 'our:service', }, - ].filter(m => metricKeys.includes(m.metric)), - } as MeasuresWrapper), + ], + } as FindingsWrapper), + ); + }), + ); + server.use( + rest.get(`${mockBaseUrl}/instanceUrl`, (req, res, ctx) => { + expect(req.url.searchParams.toString()).toBe('instanceKey='); + + return res( + ctx.json({ + instanceUrl: 'https://sonarcloud.io', + } as InstanceUrlWrapper), ); }), ); @@ -180,7 +124,9 @@ describe('SonarQubeClient', () => { identityApi: identityApiAuthenticated, }); - const summary = await client.getFindingSummary('our:service'); + const summary = await client.getFindingSummary({ + componentKey: 'our:service', + }); expect(summary).toEqual( expect.objectContaining({ lastAnalysis: '2020-01-01T00:00:00Z', @@ -210,59 +156,63 @@ describe('SonarQubeClient', () => { it('should report finding summary (custom baseUrl)', async () => { setupHandlers(); + server.use( + rest.get(`${mockBaseUrl}/instanceUrl`, (req, res, ctx) => { + expect(req.url.searchParams.toString()).toBe('instanceKey=custom'); + + return res( + ctx.json({ + instanceUrl: 'http://a.instance.local', + } as InstanceUrlWrapper), + ); + }), + ); + + server.use( + rest.get(`${mockBaseUrl}/findings`, (req, res, ctx) => { + expect(req.url.searchParams.toString()).toBe( + 'componentKey=our%3Aservice&instanceKey=custom', + ); + + return res( + ctx.json({ + analysisDate: '2020-01-03T00:00:00Z', + measures: [ + { + metric: 'alert_status', + value: 'ERROR', + }, + { + metric: 'bugs', + value: '45', + }, + { + metric: 'reliability_rating', + value: '5.0', + }, + ], + } as FindingsWrapper), + ); + }), + ); const client = new SonarQubeClient({ discoveryApi, - baseUrl: 'http://a.instance.local', identityApi: identityApiAuthenticated, }); - const summary = await client.getFindingSummary('our:service'); - - expect(summary).toEqual( - expect.objectContaining({ - lastAnalysis: '2020-01-01T00:00:00Z', - metrics: { - alert_status: 'OK', - bugs: '2', - reliability_rating: '3.0', - vulnerabilities: '4', - security_rating: '1.0', - security_hotspots_reviewed: '100', - security_review_rating: '1.0', - code_smells: '100', - sqale_rating: '2.0', - coverage: '55.5', - duplicated_lines_density: '1.0', - }, - projectUrl: 'http://a.instance.local/dashboard?id=our%3Aservice', - }) as FindingSummary, - ); - expect(summary?.getIssuesUrl('CODE_SMELL')).toEqual( - 'http://a.instance.local/project/issues?id=our%3Aservice&types=CODE_SMELL&resolved=false', - ); - expect(summary?.getComponentMeasuresUrl('COVERAGE')).toEqual( - 'http://a.instance.local/component_measures?id=our%3Aservice&metric=coverage&resolved=false&view=list', - ); - }); - - it('should only request selected metrics', async () => { - setupHandlers(['alert_status', 'bugs']); - - const client = new SonarQubeClient({ - discoveryApi, - baseUrl: 'http://a.instance.local', - identityApi: identityApiAuthenticated, + const summary = await client.getFindingSummary({ + componentKey: 'our:service', + projectInstance: 'custom', }); - const summary = await client.getFindingSummary('our:service'); - expect(summary).toEqual( expect.objectContaining({ - lastAnalysis: '2020-01-01T00:00:00Z', + lastAnalysis: '2020-01-03T00:00:00Z', metrics: { - alert_status: 'OK', - bugs: '2', + alert_status: 'ERROR', + bugs: '45', + reliability_rating: '5.0', }, projectUrl: 'http://a.instance.local/dashboard?id=our%3Aservice', }) as FindingSummary, @@ -278,25 +228,27 @@ describe('SonarQubeClient', () => { it('should add identity token for logged in users', async () => { setupHandlers(); server.use( - rest.get(`${mockBaseUrl}/sonarqube/components/show`, (req, res, ctx) => { - expect(req.url.searchParams.toString()).toBe('component=our%3Aservice'); + rest.get(`${mockBaseUrl}/findings`, (req, res, ctx) => { + expect(req.url.searchParams.toString()).toBe( + 'componentKey=our%3Aservice&instanceKey=', + ); expect(req.headers.get('Authorization')).toBe('Bearer fake-id-token'); return res( ctx.json({ - component: { - analysisDate: '2020-01-01T00:00:00Z', - }, - } as ComponentWrapper), + analysisDate: '2020-01-01T00:00:00Z', + measures: [], + } as FindingsWrapper), ); }), ); const client = new SonarQubeClient({ discoveryApi, - baseUrl: 'http://a.instance.local', identityApi: identityApiAuthenticated, }); - const summary = await client.getFindingSummary('our:service'); + const summary = await client.getFindingSummary({ + componentKey: 'our:service', + }); expect(summary?.lastAnalysis).toBe('2020-01-01T00:00:00Z'); }); @@ -304,25 +256,27 @@ describe('SonarQubeClient', () => { it('should omit identity token for guest users', async () => { setupHandlers(); server.use( - rest.get(`${mockBaseUrl}/sonarqube/components/show`, (req, res, ctx) => { - expect(req.url.searchParams.toString()).toBe('component=our%3Aservice'); + rest.get(`${mockBaseUrl}/findings`, (req, res, ctx) => { + expect(req.url.searchParams.toString()).toBe( + 'componentKey=our%3Aservice&instanceKey=', + ); expect(req.headers.has('Authorization')).toBeFalsy(); return res( ctx.json({ - component: { - analysisDate: '2020-01-01T00:00:00Z', - }, - } as ComponentWrapper), + analysisDate: '2020-01-01T00:00:00Z', + measures: [], + } as FindingsWrapper), ); }), ); const client = new SonarQubeClient({ discoveryApi, - baseUrl: 'http://a.instance.local', identityApi: identityApiGuest, }); - const summary = await client.getFindingSummary('our:service'); + const summary = await client.getFindingSummary({ + componentKey: 'our:service', + }); expect(summary?.lastAnalysis).toBe('2020-01-01T00:00:00Z'); }); diff --git a/plugins/sonarqube/src/api/SonarQubeClient.ts b/plugins/sonarqube/src/api/SonarQubeClient.ts index 39d0f11369..9ec40e8420 100644 --- a/plugins/sonarqube/src/api/SonarQubeClient.ts +++ b/plugins/sonarqube/src/api/SonarQubeClient.ts @@ -16,26 +16,22 @@ import fetch from 'cross-fetch'; import { FindingSummary, Metrics, SonarQubeApi } from './SonarQubeApi'; -import { ComponentWrapper, MeasuresWrapper } from './types'; +import { InstanceUrlWrapper, FindingsWrapper } from './types'; import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api'; export class SonarQubeClient implements SonarQubeApi { discoveryApi: DiscoveryApi; - baseUrl: string; identityApi: IdentityApi; constructor({ discoveryApi, identityApi, - baseUrl = 'https://sonarcloud.io/', }: { discoveryApi: DiscoveryApi; identityApi: IdentityApi; - baseUrl?: string; }) { this.discoveryApi = discoveryApi; this.identityApi = identityApi; - this.baseUrl = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`; } private async callApi( @@ -44,7 +40,7 @@ export class SonarQubeClient implements SonarQubeApi { ): Promise { const { token: idToken } = await this.identityApi.getCredentials(); - const apiUrl = `${await this.discoveryApi.getBaseUrl('proxy')}/sonarqube`; + const apiUrl = `${await this.discoveryApi.getBaseUrl('sonarqube')}`; const response = await fetch( `${apiUrl}/${path}?${new URLSearchParams(query).toString()}`, { @@ -60,40 +56,18 @@ export class SonarQubeClient implements SonarQubeApi { return undefined; } - private async getSupportedMetrics(): Promise { - const metrics: string[] = []; - let nextPage: number = 1; - - for (;;) { - const result = await this.callApi<{ - metrics: Array<{ key: string }>; - total: number; - }>('metrics/search', { ps: 500, p: nextPage }); - - metrics.push(...(result?.metrics?.map(m => m.key) ?? [])); - - if (result && metrics.length < result.total) { - nextPage++; - continue; - } - - return metrics; - } - } - - async getFindingSummary( - componentKey?: string, - ): Promise { + async getFindingSummary({ + componentKey, + projectInstance, + }: { + componentKey?: string; + projectInstance?: string; + } = {}): Promise { if (!componentKey) { return undefined; } - const component = await this.callApi('components/show', { - component: componentKey, - }); - if (!component) { - return undefined; - } + const instanceKey = projectInstance || ''; const metrics: Metrics = { alert_status: undefined, @@ -109,44 +83,49 @@ export class SonarQubeClient implements SonarQubeApi { duplicated_lines_density: undefined, }; - // select the metrics that are supported by the SonarQube instance - const supportedMetrics = await this.getSupportedMetrics(); - const metricKeys = Object.keys(metrics).filter(m => - supportedMetrics.includes(m), + const baseUrlWrapper = await this.callApi( + 'instanceUrl', + { + instanceKey, + }, ); + let baseUrl = baseUrlWrapper?.instanceUrl; + if (!baseUrl) { + return undefined; + } + // ensure trailing slash for later on + if (!baseUrl.endsWith('/')) { + baseUrl += '/'; + } - const measures = await this.callApi('measures/search', { - projectKeys: componentKey, - metricKeys: metricKeys.join(','), + const findings = await this.callApi('findings', { + componentKey, + instanceKey, }); - if (!measures) { + if (!findings) { return undefined; } - measures.measures - .filter(m => m.component === componentKey) - .forEach(m => { - metrics[m.metric] = m.value; - }); + findings.measures.forEach(m => { + metrics[m.metric] = m.value; + }); return { - lastAnalysis: component.component.analysisDate, + lastAnalysis: findings.analysisDate, metrics, - projectUrl: `${this.baseUrl}dashboard?id=${encodeURIComponent( - componentKey, - )}`, + projectUrl: `${baseUrl}dashboard?id=${encodeURIComponent(componentKey)}`, getIssuesUrl: identifier => - `${this.baseUrl}project/issues?id=${encodeURIComponent( + `${baseUrl}project/issues?id=${encodeURIComponent( componentKey, )}&types=${identifier.toLocaleUpperCase('en-US')}&resolved=false`, getComponentMeasuresUrl: identifier => - `${this.baseUrl}component_measures?id=${encodeURIComponent( + `${baseUrl}component_measures?id=${encodeURIComponent( componentKey, )}&metric=${identifier.toLocaleLowerCase( 'en-US', )}&resolved=false&view=list`, getSecurityHotspotsUrl: () => - `${this.baseUrl}project/security_hotspots?id=${encodeURIComponent( + `${baseUrl}project/security_hotspots?id=${encodeURIComponent( componentKey, )}`, }; diff --git a/plugins/sonarqube/src/api/types.ts b/plugins/sonarqube/src/api/types.ts index 6e951f9d8b..348986149d 100644 --- a/plugins/sonarqube/src/api/types.ts +++ b/plugins/sonarqube/src/api/types.ts @@ -14,15 +14,12 @@ * limitations under the License. */ -export interface ComponentWrapper { - component: Component; +export interface InstanceUrlWrapper { + instanceUrl: string; } -export interface Component { +export interface FindingsWrapper { analysisDate: string; -} - -export interface MeasuresWrapper { measures: Measure[]; } @@ -55,7 +52,6 @@ export type MetricKey = export interface Measure { metric: MetricKey; value: string; - component: string; } export type SonarUrlProcessorFunc = (identifier: string) => string; diff --git a/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx b/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx index 4527c2a3e3..b32a66aaa3 100644 --- a/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx +++ b/plugins/sonarqube/src/components/SonarQubeCard/SonarQubeCard.tsx @@ -26,13 +26,12 @@ import useAsync from 'react-use/lib/useAsync'; import { sonarQubeApiRef } from '../../api'; import { SONARQUBE_PROJECT_KEY_ANNOTATION, - useProjectKey, + useProjectInfo, } from '../useProjectKey'; import { Percentage } from './Percentage'; import { Rating } from './Rating'; import { RatingCard } from './RatingCard'; import { Value } from './Value'; - import { EmptyState, InfoCard, @@ -40,7 +39,6 @@ import { MissingAnnotationEmptyState, Progress, } from '@backstage/core-components'; - import { useApi } from '@backstage/core-plugin-api'; const useStyles = makeStyles(theme => ({ @@ -72,7 +70,8 @@ const useStyles = makeStyles(theme => ({ }, })); -type DuplicationRating = { +/** @public */ +export type DuplicationRating = { greaterThan: number; rating: '1.0' | '2.0' | '3.0' | '4.0' | '5.0'; }; @@ -85,20 +84,26 @@ const defaultDuplicationRatings: DuplicationRating[] = [ { greaterThan: 20, rating: '5.0' }, ]; -export const SonarQubeCard = ({ - variant = 'gridItem', - duplicationRatings = defaultDuplicationRatings, -}: { +/** @public */ +export const SonarQubeCard = (props: { variant?: InfoCardVariants; duplicationRatings?: DuplicationRating[]; }) => { + const { + variant = 'gridItem', + duplicationRatings = defaultDuplicationRatings, + } = props; const { entity } = useEntity(); const sonarQubeApi = useApi(sonarQubeApiRef); - const projectTitle = useProjectKey(entity); + const { projectKey: projectTitle, projectInstance } = useProjectInfo(entity); const { value, loading } = useAsync( - async () => sonarQubeApi.getFindingSummary(projectTitle), + async () => + sonarQubeApi.getFindingSummary({ + componentKey: projectTitle, + projectInstance: projectInstance, + }), [sonarQubeApi, projectTitle], ); diff --git a/plugins/sonarqube/src/components/SonarQubeCard/Value.tsx b/plugins/sonarqube/src/components/SonarQubeCard/Value.tsx index 58fb401ba1..a166f62a89 100644 --- a/plugins/sonarqube/src/components/SonarQubeCard/Value.tsx +++ b/plugins/sonarqube/src/components/SonarQubeCard/Value.tsx @@ -27,8 +27,7 @@ const useStyles = makeStyles((theme: BackstageTheme) => { }; }); -export const Value = ({ value }: { value?: string }) => { +export const Value = (props: { value?: string }) => { const classes = useStyles(); - - return {value}; + return {props.value}; }; diff --git a/plugins/sonarqube/src/components/SonarQubeCard/index.ts b/plugins/sonarqube/src/components/SonarQubeCard/index.ts index 44ab809439..307a9abc41 100644 --- a/plugins/sonarqube/src/components/SonarQubeCard/index.ts +++ b/plugins/sonarqube/src/components/SonarQubeCard/index.ts @@ -14,4 +14,5 @@ * limitations under the License. */ +export type { DuplicationRating } from './SonarQubeCard'; export { SonarQubeCard } from './SonarQubeCard'; diff --git a/plugins/sonarqube/src/components/useProjectKey.test.ts b/plugins/sonarqube/src/components/useProjectKey.test.ts new file mode 100644 index 0000000000..921e9455c0 --- /dev/null +++ b/plugins/sonarqube/src/components/useProjectKey.test.ts @@ -0,0 +1,100 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + isSonarQubeAvailable, + SONARQUBE_PROJECT_INSTANCE_SEPARATOR, + SONARQUBE_PROJECT_KEY_ANNOTATION, + useProjectInfo, +} from './useProjectKey'; +import { Entity } from '@backstage/catalog-model'; + +const createDummyEntity = (sonarqubeAnnotationValue: string): Entity => { + return { + apiVersion: '', + kind: '', + metadata: { + name: 'dummy', + annotations: { + [SONARQUBE_PROJECT_KEY_ANNOTATION]: sonarqubeAnnotationValue, + }, + }, + }; +}; + +describe('isSonarQubeAvailable', () => { + it('returns true if sonarqube annotation defined', () => { + const entity = createDummyEntity('dummy'); + expect(isSonarQubeAvailable(entity)).toBe(true); + }); + it('returns false if sonarqube annotation empty', () => { + const entity = createDummyEntity(''); + expect(isSonarQubeAvailable(entity)).toBe(false); + }); + it('returns false if sonarqube annotation not defined', () => { + const entity = { + apiVersion: '', + kind: '', + metadata: { + name: 'dummy', + annotations: {}, + }, + }; + expect(isSonarQubeAvailable(entity)).toBe(false); + }); +}); + +describe('useProjectInfo', () => { + const DUMMY_INSTANCE = 'dummyInstance'; + const DUMMY_KEY = 'dummyKey'; + it('parse annotation with key and instance', () => { + const entity = createDummyEntity( + DUMMY_INSTANCE + SONARQUBE_PROJECT_INSTANCE_SEPARATOR + DUMMY_KEY, + ); + expect(useProjectInfo(entity)).toEqual({ + projectInstance: DUMMY_INSTANCE, + projectKey: DUMMY_KEY, + }); + }); + // compatibility with previous mono-instance sonarqube config + it('parse annotation with only key', () => { + const entity = createDummyEntity(DUMMY_KEY); + expect(useProjectInfo(entity)).toEqual({ + projectInstance: undefined, + projectKey: DUMMY_KEY, + }); + }); + it('handle empty annotation', () => { + const entity = createDummyEntity(''); + expect(useProjectInfo(entity)).toEqual({ + projectInstance: undefined, + projectKey: undefined, + }); + }); + it('handle non-existent annotation', () => { + const entity = { + apiVersion: '', + kind: '', + metadata: { + name: 'dummy', + annotations: {}, + }, + }; + expect(useProjectInfo(entity)).toEqual({ + projectInstance: undefined, + projectKey: undefined, + }); + }); +}); diff --git a/plugins/sonarqube/src/components/useProjectKey.ts b/plugins/sonarqube/src/components/useProjectKey.ts index 18596a8171..59a572a6c4 100644 --- a/plugins/sonarqube/src/components/useProjectKey.ts +++ b/plugins/sonarqube/src/components/useProjectKey.ts @@ -17,10 +17,39 @@ import { Entity } from '@backstage/catalog-model'; export const SONARQUBE_PROJECT_KEY_ANNOTATION = 'sonarqube.org/project-key'; +export const SONARQUBE_PROJECT_INSTANCE_SEPARATOR = '/'; +/** @public */ export const isSonarQubeAvailable = (entity: Entity) => Boolean(entity.metadata.annotations?.[SONARQUBE_PROJECT_KEY_ANNOTATION]); -export const useProjectKey = (entity: Entity) => { - return entity?.metadata.annotations?.[SONARQUBE_PROJECT_KEY_ANNOTATION] ?? ''; +/** + * Try to parse sonarqube information from an entity. + * + * If part or all info are not found, they will default to undefined + * + * @param entity entity to find the sonarqube information from. + * @return a ProjectInfo properly populated. + */ +export const useProjectInfo = ( + entity: Entity, +): { + projectInstance: string | undefined; + projectKey: string | undefined; +} => { + let projectInstance = undefined; + let projectKey = undefined; + const annotation = + entity?.metadata.annotations?.[SONARQUBE_PROJECT_KEY_ANNOTATION]; + if (annotation) { + if (annotation.indexOf(SONARQUBE_PROJECT_INSTANCE_SEPARATOR) > -1) { + [projectInstance, projectKey] = annotation.split( + SONARQUBE_PROJECT_INSTANCE_SEPARATOR, + 2, + ); + } else { + projectKey = annotation; + } + } + return { projectInstance, projectKey }; }; diff --git a/plugins/sonarqube/src/plugin.ts b/plugins/sonarqube/src/plugin.ts index 5662a41f2f..0ea62de492 100644 --- a/plugins/sonarqube/src/plugin.ts +++ b/plugins/sonarqube/src/plugin.ts @@ -16,7 +16,6 @@ import { sonarQubeApiRef, SonarQubeClient } from './api'; import { - configApiRef, createApiFactory, createComponentExtension, createPlugin, @@ -24,26 +23,26 @@ import { identityApiRef, } from '@backstage/core-plugin-api'; +/** @public */ export const sonarQubePlugin = createPlugin({ id: 'sonarqube', apis: [ createApiFactory({ api: sonarQubeApiRef, deps: { - configApi: configApiRef, discoveryApi: discoveryApiRef, identityApi: identityApiRef, }, - factory: ({ configApi, discoveryApi, identityApi }) => + factory: ({ discoveryApi, identityApi }) => new SonarQubeClient({ discoveryApi, - baseUrl: configApi.getOptionalString('sonarQube.baseUrl'), identityApi, }), }), ], }); +/** @public */ export const EntitySonarQubeCard = sonarQubePlugin.provide( createComponentExtension({ name: 'EntitySonarQubeCard', diff --git a/plugins/splunk-on-call/CHANGELOG.md b/plugins/splunk-on-call/CHANGELOG.md index 354204d7a3..9bedb8334b 100644 --- a/plugins/splunk-on-call/CHANGELOG.md +++ b/plugins/splunk-on-call/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-splunk-on-call +## 0.3.32 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.3.32-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.3.32-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.3.31 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + ## 0.3.31-next.3 ### Patch Changes diff --git a/plugins/splunk-on-call/api-report.md b/plugins/splunk-on-call/api-report.md index 60ec38ca6d..b24a68e07a 100644 --- a/plugins/splunk-on-call/api-report.md +++ b/plugins/splunk-on-call/api-report.md @@ -98,6 +98,7 @@ const splunkOnCallPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; export { splunkOnCallPlugin as plugin }; diff --git a/plugins/splunk-on-call/package.json b/plugins/splunk-on-call/package.json index bb3ad8b58a..1e496f5402 100644 --- a/plugins/splunk-on-call/package.json +++ b/plugins/splunk-on-call/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-splunk-on-call", "description": "A Backstage plugin that integrates towards Splunk On-Call", - "version": "0.3.31-next.3", + "version": "0.3.32", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,11 +34,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -51,18 +51,18 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", - "@types/luxon": "^2.0.4", + "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "configSchema": "config.d.ts", "files": [ diff --git a/plugins/stack-overflow-backend/CHANGELOG.md b/plugins/stack-overflow-backend/CHANGELOG.md index 6c19f2bfe4..4ba519ba73 100644 --- a/plugins/stack-overflow-backend/CHANGELOG.md +++ b/plugins/stack-overflow-backend/CHANGELOG.md @@ -1,5 +1,25 @@ # @backstage/plugin-stack-overflow-backend +## 0.1.4 + +### Patch Changes + +- ea5631a8b2: Added API key as separate configuration + +## 0.1.4-next.0 + +### Patch Changes + +- ea5631a8b2: Added API key as separate configuration + +## 0.1.3 + +### Patch Changes + +- 52b4f796e3: app-config is now picked up properly. +- Updated dependencies + - @backstage/plugin-search-common@1.0.0 + ## 0.1.3-next.0 ### Patch Changes diff --git a/plugins/stack-overflow-backend/README.md b/plugins/stack-overflow-backend/README.md index f2eaf660c2..62115b889c 100644 --- a/plugins/stack-overflow-backend/README.md +++ b/plugins/stack-overflow-backend/README.md @@ -15,6 +15,16 @@ stackoverflow: baseUrl: https://api.stackexchange.com/2.2 # alternative: your internal stack overflow instance ``` +### Stack Overflow for Teams (private stack overflow instance) + +If you have a private stack overflow instance you will need to supply an API key as well. You can read more about how to set this up by going to [Stack Overflows Help Page](https://stackoverflow.help/en/articles/4385859-stack-overflow-for-teams-api) + +```yaml +stackoverflow: + baseUrl: https://api.stackexchange.com/2.2 # alternative: your internal stack overflow instance + apiKey: $STACK_OVERFLOW_API_KEY +``` + ## Areas of Responsibility This stack overflow backend plugin is primarily responsible for the following: diff --git a/plugins/stack-overflow-backend/api-report.md b/plugins/stack-overflow-backend/api-report.md index fc4c610d3e..1a21ff34ac 100644 --- a/plugins/stack-overflow-backend/api-report.md +++ b/plugins/stack-overflow-backend/api-report.md @@ -41,6 +41,7 @@ export class StackOverflowQuestionsCollatorFactory // @public export type StackOverflowQuestionsCollatorFactoryOptions = { baseUrl?: string; + apiKey?: string; requestParams: StackOverflowQuestionsRequestParams; logger: Logger; }; diff --git a/plugins/stack-overflow-backend/config.d.ts b/plugins/stack-overflow-backend/config.d.ts index 2c39d61bfb..d329a4389f 100644 --- a/plugins/stack-overflow-backend/config.d.ts +++ b/plugins/stack-overflow-backend/config.d.ts @@ -24,5 +24,11 @@ export interface Config { * @visibility backend */ baseUrl?: string; + + /** + * The api key to authenticate to Stack Overflow API + * @visibility secret + */ + apiKey?: string; }; } diff --git a/plugins/stack-overflow-backend/package.json b/plugins/stack-overflow-backend/package.json index 07cdbfb242..9f75578252 100644 --- a/plugins/stack-overflow-backend/package.json +++ b/plugins/stack-overflow-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow-backend", - "version": "0.1.3-next.0", + "version": "0.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,7 +33,7 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/plugin-search-common": "^0.3.6-next.0", + "@backstage/plugin-search-common": "^1.0.0", "@backstage/config": "^1.0.1", "qs": "^6.9.4", "cross-fetch": "^3.1.5", diff --git a/plugins/stack-overflow-backend/src/search/StackOverflowQuestionsCollatorFactory.ts b/plugins/stack-overflow-backend/src/search/StackOverflowQuestionsCollatorFactory.ts index 98fc86c2ea..45261ce546 100644 --- a/plugins/stack-overflow-backend/src/search/StackOverflowQuestionsCollatorFactory.ts +++ b/plugins/stack-overflow-backend/src/search/StackOverflowQuestionsCollatorFactory.ts @@ -50,6 +50,7 @@ export type StackOverflowQuestionsRequestParams = { */ export type StackOverflowQuestionsCollatorFactoryOptions = { baseUrl?: string; + apiKey?: string; requestParams: StackOverflowQuestionsRequestParams; logger: Logger; }; @@ -64,11 +65,13 @@ export class StackOverflowQuestionsCollatorFactory { protected requestParams: StackOverflowQuestionsRequestParams; private readonly baseUrl: string | undefined; + private readonly apiKey: string | undefined; private readonly logger: Logger; public readonly type: string = 'stack-overflow'; private constructor(options: StackOverflowQuestionsCollatorFactoryOptions) { this.baseUrl = options.baseUrl; + this.apiKey = options.apiKey; this.requestParams = options.requestParams; this.logger = options.logger; } @@ -77,10 +80,15 @@ export class StackOverflowQuestionsCollatorFactory config: Config, options: StackOverflowQuestionsCollatorFactoryOptions, ) { + const apiKey = config.getOptionalString('stackoverflow.apiKey'); const baseUrl = config.getOptionalString('stackoverflow.baseUrl') || 'https://api.stackexchange.com/2.2'; - return new StackOverflowQuestionsCollatorFactory({ ...options, baseUrl }); + return new StackOverflowQuestionsCollatorFactory({ + ...options, + baseUrl, + apiKey, + }); } async getCollator() { @@ -93,12 +101,28 @@ export class StackOverflowQuestionsCollatorFactory `No stackoverflow.baseUrl configured in your app-config.yaml`, ); } + + try { + if (Object.keys(this.requestParams).indexOf('key') >= 0) { + this.logger.warn( + 'The API Key should be passed as a seperate param to bypass encoding', + ); + delete this.requestParams.key; + } + } catch (e) { + this.logger.error(`Caught ${e}`); + } + const params = qs.stringify(this.requestParams, { arrayFormat: 'comma', addQueryPrefix: true, }); - const res = await fetch(`${this.baseUrl}/questions${params}`); + const apiKeyParam = this.apiKey + ? `${params ? '&' : '?'}key=${this.apiKey}` + : ''; + + const res = await fetch(`${this.baseUrl}/questions${params}${apiKeyParam}`); const data = await res.json(); for (const question of data.items) { diff --git a/plugins/stack-overflow/CHANGELOG.md b/plugins/stack-overflow/CHANGELOG.md index 36a85b361d..193f0f4b6e 100644 --- a/plugins/stack-overflow/CHANGELOG.md +++ b/plugins/stack-overflow/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-stack-overflow +## 0.1.4 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-home@0.4.24 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.1.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + - @backstage/plugin-home@0.4.24-next.2 + +## 0.1.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-home@0.4.24-next.0 + +## 0.1.3 + +### Patch Changes + +- 12ae3eed2f: - Publicly exports `StackOverflowIcon`. + - `HomePageStackOverflowQuestions` accepts optional icon property. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 52b4f796e3: app-config is now picked up properly. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-home@0.4.23 + - @backstage/theme@0.2.16 + ## 0.1.3-next.3 ### Patch Changes diff --git a/plugins/stack-overflow/api-report.md b/plugins/stack-overflow/api-report.md index e4912fcd18..9404c74700 100644 --- a/plugins/stack-overflow/api-report.md +++ b/plugins/stack-overflow/api-report.md @@ -20,7 +20,7 @@ export const HomePageStackOverflowQuestions: ( export const StackOverflowIcon: () => JSX.Element; // @public -export const stackOverflowPlugin: BackstagePlugin<{}, {}>; +export const stackOverflowPlugin: BackstagePlugin<{}, {}, {}>; // @public export type StackOverflowQuestion = { diff --git a/plugins/stack-overflow/package.json b/plugins/stack-overflow/package.json index 48f5165520..c8a5d36c65 100644 --- a/plugins/stack-overflow/package.json +++ b/plugins/stack-overflow/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-stack-overflow", - "version": "0.1.3-next.3", + "version": "0.1.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,11 +24,11 @@ }, "dependencies": { "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/plugin-home": "^0.4.23-next.3", - "@backstage/plugin-search-common": "^0.3.6-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/plugin-home": "^0.4.24", + "@backstage/plugin-search-common": "^1.0.0", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@testing-library/jest-dom": "^5.10.1", @@ -42,15 +42,15 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md index 9c509c4807..c6e8bd0d0a 100644 --- a/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md +++ b/plugins/tech-insights-backend-module-jsonfc/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-tech-insights-backend-module-jsonfc +## 0.1.19 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-tech-insights-common@0.2.6 + - @backstage/plugin-tech-insights-node@0.3.3 + +## 0.1.19-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-tech-insights-common@0.2.6-next.0 + - @backstage/plugin-tech-insights-node@0.3.3-next.0 + +## 0.1.18 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-tech-insights-common@0.2.5 + - @backstage/plugin-tech-insights-node@0.3.2 + - @backstage/errors@1.1.0 + ## 0.1.18-next.2 ### Patch Changes diff --git a/plugins/tech-insights-backend-module-jsonfc/package.json b/plugins/tech-insights-backend-module-jsonfc/package.json index a6fdfb69ce..3a7191e429 100644 --- a/plugins/tech-insights-backend-module-jsonfc/package.json +++ b/plugins/tech-insights-backend-module-jsonfc/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend-module-jsonfc", - "version": "0.1.18-next.2", + "version": "0.1.19", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,11 +34,11 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", + "@backstage/backend-common": "^0.15.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-tech-insights-common": "^0.2.5-next.0", - "@backstage/plugin-tech-insights-node": "^0.3.2-next.1", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-tech-insights-common": "^0.2.6", + "@backstage/plugin-tech-insights-node": "^0.3.3", "ajv": "^8.10.0", "json-rules-engine": "^6.1.2", "lodash": "^4.17.21", @@ -46,7 +46,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3" + "@backstage/cli": "^0.18.1" }, "files": [ "dist" diff --git a/plugins/tech-insights-backend/CHANGELOG.md b/plugins/tech-insights-backend/CHANGELOG.md index b10f03269b..a9178622a9 100644 --- a/plugins/tech-insights-backend/CHANGELOG.md +++ b/plugins/tech-insights-backend/CHANGELOG.md @@ -1,5 +1,49 @@ # @backstage/plugin-tech-insights-backend +## 0.5.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-tasks@0.3.4 + - @backstage/plugin-tech-insights-common@0.2.6 + - @backstage/plugin-tech-insights-node@0.3.3 + +## 0.5.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/plugin-tech-insights-common@0.2.6-next.0 + - @backstage/plugin-tech-insights-node@0.3.3-next.0 + +## 0.5.0 + +### Minor Changes + +- 818fa28d71: Allow FactRetrieverRegistry to be injected into buildTechInsightsContext so that we can override default registry implementation. +- 46cfda58aa: **BREAKING**: Update FactRetrieverRegistry interface to be async so that db backed implementations can be passed through to the FactRetrieverEngine. + + If you have existing custom `FactRetrieverRegistry` implementations, you'll need to remove the `retrievers` member and make all the methods async. + +### Patch Changes + +- 2ef58ab539: TechInsightsBackend: Added missing 'scheduler' to code examples +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- bcc122c46d: The `FactRetriever` model has been extended by adding optional title and description fields, allowing you to display them in the UI. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/catalog-client@1.0.4 + - @backstage/backend-tasks@0.3.3 + - @backstage/plugin-tech-insights-common@0.2.5 + - @backstage/plugin-tech-insights-node@0.3.2 + - @backstage/errors@1.1.0 + ## 0.5.0-next.3 ### Minor Changes diff --git a/plugins/tech-insights-backend/package.json b/plugins/tech-insights-backend/package.json index 786469410b..dbc39d9e2c 100644 --- a/plugins/tech-insights-backend/package.json +++ b/plugins/tech-insights-backend/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-backend", - "version": "0.5.0-next.3", + "version": "0.5.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,14 +34,14 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/backend-tasks": "^0.3.3-next.3", - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-tasks": "^0.3.4", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-tech-insights-common": "^0.2.5-next.0", - "@backstage/plugin-tech-insights-node": "^0.3.2-next.1", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-tech-insights-common": "^0.2.6", + "@backstage/plugin-tech-insights-node": "^0.3.3", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -54,9 +54,9 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", - "@types/luxon": "^2.0.5", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", + "@types/luxon": "^2.0.5", "@types/supertest": "^2.0.8", "@types/semver": "^7.3.8", "supertest": "^6.1.3", diff --git a/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.test.ts b/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.test.ts index e7e8819c66..3cf6d08c65 100644 --- a/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.test.ts +++ b/plugins/tech-insights-backend/src/service/persistence/TechInsightsDatabase.test.ts @@ -15,7 +15,7 @@ */ import { DateTime, Duration } from 'luxon'; import { TechInsightsStore } from '@backstage/plugin-tech-insights-node'; -import { Knex } from 'knex'; +import { Knex as KnexType, Knex } from 'knex'; import { TestDatabases } from '@backstage/backend-test-utils'; import { getVoidLogger } from '@backstage/backend-common'; import { initializePersistenceContext } from './persistenceContext'; @@ -165,15 +165,28 @@ const multipleSameFacts = [ }, ]; +function createDatabaseManager( + client: KnexType, + skipMigrations: boolean = false, +) { + return { + getClient: async () => client, + migrations: { + skip: skipMigrations, + }, + }; +} + describe('Tech Insights database', () => { const databases = TestDatabases.create(); let store: TechInsightsStore; let testDbClient: Knex; beforeAll(async () => { testDbClient = await databases.init('SQLITE_3'); + const database = createDatabaseManager(testDbClient); store = ( - await initializePersistenceContext(testDbClient, { + await initializePersistenceContext(database, { logger: getVoidLogger(), }) ).techInsightsStore; diff --git a/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts b/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts index b0fb65349f..575ee67bdf 100644 --- a/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts +++ b/plugins/tech-insights-backend/src/service/persistence/persistenceContext.ts @@ -13,8 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { getVoidLogger, resolvePackagePath } from '@backstage/backend-common'; -import { Knex } from 'knex'; +import { + getVoidLogger, + PluginDatabaseManager, + resolvePackagePath, +} from '@backstage/backend-common'; import { Logger } from 'winston'; import { TechInsightsDatabase } from './TechInsightsDatabase'; import { TechInsightsStore } from '@backstage/plugin-tech-insights-node'; @@ -47,13 +50,18 @@ const defaultOptions: CreateDatabaseOptions = { * @public */ export const initializePersistenceContext = async ( - knex: Knex, + database: PluginDatabaseManager, options: CreateDatabaseOptions = defaultOptions, ): Promise => { - await knex.migrate.latest({ - directory: migrationsDir, - }); + const client = await database.getClient(); + + if (!database.migrations?.skip) { + await client.migrate.latest({ + directory: migrationsDir, + }); + } + return { - techInsightsStore: new TechInsightsDatabase(knex, options.logger), + techInsightsStore: new TechInsightsDatabase(client, options.logger), }; }; diff --git a/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts b/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts index fb19fab359..f85d99b2a8 100644 --- a/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts +++ b/plugins/tech-insights-backend/src/service/techInsightsContextBuilder.ts @@ -139,10 +139,9 @@ export const buildTechInsightsContext = async < const factRetrieverRegistry = buildFactRetrieverRegistry(); - const persistenceContext = await initializePersistenceContext( - await database.getClient(), - { logger }, - ); + const persistenceContext = await initializePersistenceContext(database, { + logger, + }); const factRetrieverEngine = await DefaultFactRetrieverEngine.create({ scheduler, diff --git a/plugins/tech-insights-common/CHANGELOG.md b/plugins/tech-insights-common/CHANGELOG.md index 5713bbb1b3..0482f80fb0 100644 --- a/plugins/tech-insights-common/CHANGELOG.md +++ b/plugins/tech-insights-common/CHANGELOG.md @@ -1,5 +1,23 @@ # @backstage/plugin-tech-insights-common +## 0.2.6 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. + +## 0.2.6-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. + +## 0.2.5 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. + ## 0.2.5-next.0 ### Patch Changes diff --git a/plugins/tech-insights-common/package.json b/plugins/tech-insights-common/package.json index f06f33e9c1..1b5dabb88d 100644 --- a/plugins/tech-insights-common/package.json +++ b/plugins/tech-insights-common/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-common", - "version": "0.2.5-next.0", + "version": "0.2.6", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,12 +33,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@types/luxon": "^2.0.5", + "@types/luxon": "^3.0.0", "luxon": "^3.0.0", "@backstage/types": "^1.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3" + "@backstage/cli": "^0.18.1" }, "files": [ "dist" diff --git a/plugins/tech-insights-node/CHANGELOG.md b/plugins/tech-insights-node/CHANGELOG.md index 69ff7c8b04..36650980e8 100644 --- a/plugins/tech-insights-node/CHANGELOG.md +++ b/plugins/tech-insights-node/CHANGELOG.md @@ -1,5 +1,33 @@ # @backstage/plugin-tech-insights-node +## 0.3.3 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/plugin-tech-insights-common@0.2.6 + +## 0.3.3-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/plugin-tech-insights-common@0.2.6-next.0 + +## 0.3.2 + +### Patch Changes + +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- bcc122c46d: The `FactRetriever` model has been extended by adding optional title and description fields, allowing you to display them in the UI. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/plugin-tech-insights-common@0.2.5 + ## 0.3.2-next.1 ### Patch Changes diff --git a/plugins/tech-insights-node/api-report.md b/plugins/tech-insights-node/api-report.md index 84677bdcbc..19645d604b 100644 --- a/plugins/tech-insights-node/api-report.md +++ b/plugins/tech-insights-node/api-report.md @@ -169,11 +169,7 @@ export interface TechInsightsStore { [factRef: string]: FlatTechInsightFact; }>; getLatestSchemas(ids?: string[]): Promise; - insertFacts({ - id, - facts, - lifecycle, - }: { + insertFacts(options: { id: string; facts: TechInsightFact[]; lifecycle?: FactLifecycle; diff --git a/plugins/tech-insights-node/package.json b/plugins/tech-insights-node/package.json index 1c05079cb5..0233fac050 100644 --- a/plugins/tech-insights-node/package.json +++ b/plugins/tech-insights-node/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights-node", - "version": "0.3.2-next.1", + "version": "0.3.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -33,16 +33,16 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", + "@backstage/backend-common": "^0.15.0", "@backstage/config": "^1.0.1", - "@backstage/plugin-tech-insights-common": "^0.2.5-next.0", + "@backstage/plugin-tech-insights-common": "^0.2.6", "@backstage/types": "^1.0.0", - "@types/luxon": "^2.0.5", + "@types/luxon": "^3.0.0", "luxon": "^3.0.0", "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3" + "@backstage/cli": "^0.18.1" }, "files": [ "dist" diff --git a/plugins/tech-insights-node/src/persistence.ts b/plugins/tech-insights-node/src/persistence.ts index 4324c24c42..31fda403a8 100644 --- a/plugins/tech-insights-node/src/persistence.ts +++ b/plugins/tech-insights-node/src/persistence.ts @@ -38,11 +38,7 @@ export interface TechInsightsStore { * @param facts - A collection of TechInsightFacts * @param lifecycle - (Optional) Fact lifecycle object indicating the expiration logic for these items */ - insertFacts({ - id, - facts, - lifecycle, - }: { + insertFacts(options: { id: string; facts: TechInsightFact[]; lifecycle?: FactLifecycle; diff --git a/plugins/tech-insights/CHANGELOG.md b/plugins/tech-insights/CHANGELOG.md index c2d408757e..b80355146d 100644 --- a/plugins/tech-insights/CHANGELOG.md +++ b/plugins/tech-insights/CHANGELOG.md @@ -1,5 +1,48 @@ # @backstage/plugin-tech-insights +## 0.2.4 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-tech-insights-common@0.2.6 + +## 0.2.4-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.2.4-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-tech-insights-common@0.2.6-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.2.3 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-tech-insights-common@0.2.5 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.2.3-next.3 ### Patch Changes diff --git a/plugins/tech-insights/api-report.md b/plugins/tech-insights/api-report.md index 54884f12ea..4f2687fa48 100644 --- a/plugins/tech-insights/api-report.md +++ b/plugins/tech-insights/api-report.md @@ -33,22 +33,14 @@ export type CheckResultRenderer = { }; // @public (undocumented) -export const EntityTechInsightsScorecardCard: ({ - title, - description, - checksId, -}: { +export const EntityTechInsightsScorecardCard: (props: { title?: string | undefined; description?: string | undefined; checksId?: string[] | undefined; }) => JSX.Element; // @public (undocumented) -export const EntityTechInsightsScorecardContent: ({ - title, - description, - checksId, -}: { +export const EntityTechInsightsScorecardContent: (props: { title?: string | undefined; description?: string | undefined; checksId?: string[] | undefined; @@ -112,6 +104,7 @@ export const techInsightsPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; diff --git a/plugins/tech-insights/package.json b/plugins/tech-insights/package.json index bca772d70b..2c33001ef3 100644 --- a/plugins/tech-insights/package.json +++ b/plugins/tech-insights/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-tech-insights", - "version": "0.2.3-next.3", + "version": "0.2.4", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -28,13 +28,13 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/plugin-tech-insights-common": "^0.2.5-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/plugin-tech-insights-common": "^0.2.6", + "@backstage/theme": "^0.2.16", "@backstage/types": "^1.0.0", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", @@ -47,17 +47,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/tech-insights/src/components/ScorecardsCard/ScorecardsCard.tsx b/plugins/tech-insights/src/components/ScorecardsCard/ScorecardsCard.tsx index f6bc4b0cb5..57b8915b58 100644 --- a/plugins/tech-insights/src/components/ScorecardsCard/ScorecardsCard.tsx +++ b/plugins/tech-insights/src/components/ScorecardsCard/ScorecardsCard.tsx @@ -23,15 +23,12 @@ import { ScorecardInfo } from '../ScorecardsInfo'; import Alert from '@material-ui/lab/Alert'; import { techInsightsApiRef } from '../../api/TechInsightsApi'; -export const ScorecardsCard = ({ - title, - description, - checksId, -}: { +export const ScorecardsCard = (props: { title?: string; description?: string; checksId?: string[]; }) => { + const { title, description, checksId } = props; const api = useApi(techInsightsApiRef); const { namespace, kind, name } = useParams(); const { value, loading, error } = useAsync( diff --git a/plugins/tech-insights/src/components/ScorecardsContent/ScorecardContent.tsx b/plugins/tech-insights/src/components/ScorecardsContent/ScorecardContent.tsx index 07a839d7a8..c3d02c938f 100644 --- a/plugins/tech-insights/src/components/ScorecardsContent/ScorecardContent.tsx +++ b/plugins/tech-insights/src/components/ScorecardsContent/ScorecardContent.tsx @@ -31,15 +31,12 @@ const useStyles = makeStyles(() => ({ }, })); -export const ScorecardsContent = ({ - title, - description, - checksId, -}: { +export const ScorecardsContent = (props: { title?: string; description?: string; checksId?: string[]; }) => { + const { title, description, checksId } = props; const classes = useStyles(); const api = useApi(techInsightsApiRef); const { namespace, kind, name } = useParams(); diff --git a/plugins/tech-insights/src/components/ScorecardsInfo/ScorecardInfo.tsx b/plugins/tech-insights/src/components/ScorecardsInfo/ScorecardInfo.tsx index 2c5abb3596..9d5fc5ac9e 100644 --- a/plugins/tech-insights/src/components/ScorecardsInfo/ScorecardInfo.tsx +++ b/plugins/tech-insights/src/components/ScorecardsInfo/ScorecardInfo.tsx @@ -30,15 +30,9 @@ const useStyles = makeStyles((theme: BackstageTheme) => ({ }, })); -type Checks = { - checks: CheckResult[]; - title?: string; - description?: string; -}; - const infoCard = ( - title: Checks['title'], - description: Checks['description'], + title: string | undefined, + description: string | undefined, className: string, element: JSX.Element, ) => ( @@ -54,7 +48,12 @@ const infoCard = ( ); -export const ScorecardInfo = ({ checks, title, description }: Checks) => { +export const ScorecardInfo = (props: { + checks: CheckResult[]; + title?: string; + description?: string; +}) => { + const { checks, title, description } = props; const classes = useStyles(); const api = useApi(techInsightsApiRef); diff --git a/plugins/tech-radar/CHANGELOG.md b/plugins/tech-radar/CHANGELOG.md index 471196a9a9..0659f93073 100644 --- a/plugins/tech-radar/CHANGELOG.md +++ b/plugins/tech-radar/CHANGELOG.md @@ -1,5 +1,41 @@ # @backstage/plugin-tech-radar +## 0.5.15 + +### Patch Changes + +- a641f79dcb: Move CSS overflow property to quadrant block element (i.e. to a div element) in RadarLegend component. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.5.15-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.5.15-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.5.14 + +### Patch Changes + +- b8f608f1ec: Update tech-radar documentation on how to use an external json data source with dates. +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + ## 0.5.14-next.3 ### Patch Changes diff --git a/plugins/tech-radar/api-report.md b/plugins/tech-radar/api-report.md index 75824f0509..a55cf79f28 100644 --- a/plugins/tech-radar/api-report.md +++ b/plugins/tech-radar/api-report.md @@ -126,6 +126,7 @@ const techRadarPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; export { techRadarPlugin as plugin }; diff --git a/plugins/tech-radar/package.json b/plugins/tech-radar/package.json index ed1c37e2f7..b68536c1ff 100644 --- a/plugins/tech-radar/package.json +++ b/plugins/tech-radar/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-tech-radar", "description": "A Backstage plugin that lets you display a Tech Radar for your organization", - "version": "0.5.14-next.3", + "version": "0.5.15", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,9 +34,9 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -49,10 +49,10 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", @@ -62,7 +62,7 @@ "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx index 705dc9f47b..a398113b98 100644 --- a/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx +++ b/plugins/tech-radar/src/components/RadarLegend/RadarLegend.tsx @@ -32,15 +32,11 @@ export type Props = { }; const useStyles = makeStyles(theme => ({ - quadrantLegend: { - overflowY: 'auto', - scrollbarWidth: 'thin', - }, quadrant: { height: '100%', width: '100%', + overflowY: 'auto', scrollbarWidth: 'thin', - pointerEvents: 'none', }, quadrantHeading: { pointerEvents: 'none', @@ -229,7 +225,6 @@ const RadarLegend = (props: Props): JSX.Element => { y={quadrant.legendY} width={quadrant.legendWidth} height={quadrant.legendHeight} - className={classes.quadrantLegend} data-testid="radar-quadrant" >
diff --git a/plugins/techdocs-addons-test-utils/CHANGELOG.md b/plugins/techdocs-addons-test-utils/CHANGELOG.md index 0b524d9306..f10fadfec2 100644 --- a/plugins/techdocs-addons-test-utils/CHANGELOG.md +++ b/plugins/techdocs-addons-test-utils/CHANGELOG.md @@ -1,5 +1,65 @@ # @backstage/plugin-techdocs-addons-test-utils +## 1.0.3 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.3.1 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog@1.5.0 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/core-app-api@1.0.5 + - @backstage/integration-react@1.1.3 + - @backstage/test-utils@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## 1.0.3-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-techdocs@1.3.1-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-catalog@1.5.0-next.2 + - @backstage/plugin-search-react@1.0.1-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + +## 1.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog@1.5.0-next.0 + - @backstage/plugin-techdocs@1.3.1-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/core-app-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/test-utils@1.1.3-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + +## 1.0.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-catalog@1.4.0 + - @backstage/core-app-api@1.0.4 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration-react@1.1.2 + - @backstage/test-utils@1.1.2 + - @backstage/plugin-techdocs@1.3.0 + - @backstage/theme@0.2.16 + ## 1.0.2-next.3 ### Patch Changes diff --git a/plugins/techdocs-addons-test-utils/package.json b/plugins/techdocs-addons-test-utils/package.json index cf57a0c8aa..b168371441 100644 --- a/plugins/techdocs-addons-test-utils/package.json +++ b/plugins/techdocs-addons-test-utils/package.json @@ -1,6 +1,6 @@ { "name": "@backstage/plugin-techdocs-addons-test-utils", - "version": "1.0.2-next.3", + "version": "1.0.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -32,16 +32,16 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/integration-react": "^1.1.2-next.3", - "@backstage/plugin-catalog": "^1.4.0-next.3", - "@backstage/plugin-search-react": "^0.2.2-next.3", - "@backstage/plugin-techdocs": "^1.2.1-next.3", - "@backstage/plugin-techdocs-react": "^1.0.2-next.2", - "@backstage/test-utils": "^1.1.2-next.2", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-app-api": "^1.0.5", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/integration-react": "^1.1.3", + "@backstage/plugin-catalog": "^1.5.0", + "@backstage/plugin-search-react": "^1.0.1", + "@backstage/plugin-techdocs": "^1.3.1", + "@backstage/plugin-techdocs-react": "^1.0.3", + "@backstage/test-utils": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -56,14 +56,14 @@ "react-dom": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/dev-utils": "^1.0.4-next.3", + "@backstage/cli": "^0.18.1", + "@backstage/dev-utils": "^1.0.5", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", - "msw": "^0.44.0", + "msw": "^0.45.0", "cross-fetch": "^3.1.5" }, "files": [ diff --git a/plugins/techdocs-backend/CHANGELOG.md b/plugins/techdocs-backend/CHANGELOG.md index 42b2505d3a..8140808d9d 100644 --- a/plugins/techdocs-backend/CHANGELOG.md +++ b/plugins/techdocs-backend/CHANGELOG.md @@ -1,5 +1,57 @@ # @backstage/plugin-techdocs-backend +## 1.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + - @backstage/plugin-techdocs-node@1.3.0 + - @backstage/plugin-catalog-common@1.0.5 + +## 1.2.1-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-common@1.0.5-next.0 + - @backstage/backend-common@0.15.0-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-techdocs-node@1.3.0-next.1 + +## 1.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + - @backstage/plugin-techdocs-node@1.2.1-next.0 + +## 1.2.0 + +### Minor Changes + +- 860765ff45: Added local publishing target directory `config`: `techdocs.publisher.local.publishDirectory` + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 679b32172e: Updated dependency `knex` to `^2.0.0`. +- 726577958f: Add sample headings on the documented component homepage. +- Updated dependencies + - @backstage/plugin-techdocs-node@1.2.0 + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/plugin-permission-common@0.6.3 + - @backstage/errors@1.1.0 + - @backstage/plugin-catalog-common@1.0.4 + ## 1.2.0-next.3 ### Patch Changes diff --git a/plugins/techdocs-backend/package.json b/plugins/techdocs-backend/package.json index 4a1016b417..ec47ff7fbf 100644 --- a/plugins/techdocs-backend/package.json +++ b/plugins/techdocs-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-backend", "description": "The Backstage backend plugin that renders technical documentation for your components", - "version": "1.2.0-next.3", + "version": "1.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,16 +34,16 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-catalog-common": "^1.0.4-next.0", - "@backstage/plugin-permission-common": "^0.6.3-next.1", - "@backstage/plugin-search-common": "^0.3.6-next.0", - "@backstage/plugin-techdocs-node": "^1.2.0-next.3", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-catalog-common": "^1.0.5", + "@backstage/plugin-permission-common": "^0.6.3", + "@backstage/plugin-search-common": "^1.0.0", + "@backstage/plugin-techdocs-node": "^1.3.0", "@types/express": "^4.17.6", "dockerode": "^3.3.1", "express": "^4.17.1", @@ -56,11 +56,11 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/backend-test-utils": "^0.1.26-next.3", - "@backstage/cli": "^0.18.0-next.3", - "@backstage/plugin-search-backend-node": "0.6.3-next.2", + "@backstage/backend-test-utils": "^0.1.27", + "@backstage/cli": "^0.18.1", + "@backstage/plugin-search-backend-node": "1.0.1", "@types/dockerode": "^3.3.0", - "msw": "^0.44.0", + "msw": "^0.45.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/techdocs-module-addons-contrib/CHANGELOG.md b/plugins/techdocs-module-addons-contrib/CHANGELOG.md index 827da822b0..4babb601bc 100644 --- a/plugins/techdocs-module-addons-contrib/CHANGELOG.md +++ b/plugins/techdocs-module-addons-contrib/CHANGELOG.md @@ -1,5 +1,71 @@ # @backstage/plugin-techdocs-module-addons-contrib +## 1.0.3 + +### Patch Changes + +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/integration-react@1.1.3 + +## 1.0.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + +## 1.0.3-next.1 + +### Patch Changes + +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.1 + +## 1.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + +## 1.0.2 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 693990d4fe: Updated dependency `@react-hookz/web` to `^15.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/integration-react@1.1.2 + - @backstage/theme@0.2.16 + ## 1.0.2-next.3 ### Patch Changes diff --git a/plugins/techdocs-module-addons-contrib/api-report.md b/plugins/techdocs-module-addons-contrib/api-report.md index efe88e2d5c..68fad9121d 100644 --- a/plugins/techdocs-module-addons-contrib/api-report.md +++ b/plugins/techdocs-module-addons-contrib/api-report.md @@ -26,14 +26,12 @@ export type ReportIssueTemplate = { }; // @public -export type ReportIssueTemplateBuilder = ({ - selection, -}: { +export type ReportIssueTemplateBuilder = (options: { selection: Selection; }) => ReportIssueTemplate; // @public -export const techdocsModuleAddonsContribPlugin: BackstagePlugin<{}, {}>; +export const techdocsModuleAddonsContribPlugin: BackstagePlugin<{}, {}, {}>; // @public export const TextSize: () => JSX.Element | null; diff --git a/plugins/techdocs-module-addons-contrib/package.json b/plugins/techdocs-module-addons-contrib/package.json index 7228295f0f..4a1fe091ba 100644 --- a/plugins/techdocs-module-addons-contrib/package.json +++ b/plugins/techdocs-module-addons-contrib/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-module-addons-contrib", "description": "Plugin module for contributed TechDocs Addons", - "version": "1.0.2-next.3", + "version": "1.0.3", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,12 +34,12 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/integration-react": "^1.1.2-next.3", - "@backstage/plugin-techdocs-react": "^1.0.2-next.2", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/integration": "^1.3.0", + "@backstage/integration-react": "^1.1.3", + "@backstage/plugin-techdocs-react": "^1.0.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.9.13", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -51,18 +51,18 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/plugin-techdocs-addons-test-utils": "^1.0.2-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/plugin-techdocs-addons-test-utils": "^1.0.3", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "@types/react": "^16.13.1 || ^17.0.0", - "msw": "^0.44.0", + "msw": "^0.45.0", "cross-fetch": "^3.1.5" }, "files": [ diff --git a/plugins/techdocs-module-addons-contrib/src/ReportIssue/ReportIssue.tsx b/plugins/techdocs-module-addons-contrib/src/ReportIssue/ReportIssue.tsx index c8caa5ddbc..c81eacb1ee 100644 --- a/plugins/techdocs-module-addons-contrib/src/ReportIssue/ReportIssue.tsx +++ b/plugins/techdocs-module-addons-contrib/src/ReportIssue/ReportIssue.tsx @@ -118,7 +118,12 @@ export const ReportIssueAddon = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [selection, mainContent, feedbackContainer]); - if (!selection || !repository) return null; + if ( + !selection || + !repository || + !['github', 'gitlab'].includes(repository.type) + ) + return null; if (!feedbackContainer) { feedbackContainer = document.createElement('div'); diff --git a/plugins/techdocs-module-addons-contrib/src/ReportIssue/types.ts b/plugins/techdocs-module-addons-contrib/src/ReportIssue/types.ts index 0816b45d9d..84143a40f2 100644 --- a/plugins/techdocs-module-addons-contrib/src/ReportIssue/types.ts +++ b/plugins/techdocs-module-addons-contrib/src/ReportIssue/types.ts @@ -37,9 +37,7 @@ export type ReportIssueTemplate = { * * @public */ -export type ReportIssueTemplateBuilder = ({ - selection, -}: { +export type ReportIssueTemplateBuilder = (options: { selection: Selection; }) => ReportIssueTemplate; diff --git a/plugins/techdocs-node/CHANGELOG.md b/plugins/techdocs-node/CHANGELOG.md index e09c63cab9..8b1b2059cb 100644 --- a/plugins/techdocs-node/CHANGELOG.md +++ b/plugins/techdocs-node/CHANGELOG.md @@ -1,5 +1,73 @@ # @backstage/plugin-techdocs-node +## 1.3.0 + +### Minor Changes + +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer + +### Patch Changes + +- c8196bd37d: Fix AWS S3 404 NotFound error + + When reading an object from the S3 bucket through a stream, the aws-sdk getObject() API may throw a 404 NotFound Error with no error message or, in fact, any sort of HTTP-layer error responses. These fail the @backstage/error's assertError() checks, so they must be wrapped. The test for this case was also updated to match the wrapped error message. + +- f833344611: Bump default `TechDocs` image to `v1.1.0`, see the release [here](https://github.com/backstage/techdocs-container/releases/tag/v1.1.0). +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + +## 1.3.0-next.1 + +### Minor Changes + +- ad35364e97: feat(techdocs): add edit button support for bitbucketServer + +### Patch Changes + +- f833344611: Bump default `TechDocs` image to `v1.1.0`, see the release [here](https://github.com/backstage/techdocs-container/releases/tag/v1.1.0). +- Updated dependencies + - @backstage/backend-common@0.15.0-next.1 + - @backstage/integration@1.3.0-next.1 + +## 1.2.1-next.0 + +### Patch Changes + +- c8196bd37d: Fix AWS S3 404 NotFound error + + When reading an object from the S3 bucket through a stream, the aws-sdk getObject() API may throw a 404 NotFound Error with no error message or, in fact, any sort of HTTP-layer error responses. These fail the @backstage/error's assertError() checks, so they must be wrapped. The test for this case was also updated to match the wrapped error message. + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + +## 1.2.0 + +### Minor Changes + +- 860765ff45: Added local publishing target directory `config`: `techdocs.publisher.local.publishDirectory` + +### Patch Changes + +- a5d73da942: Fix the flag parsing for `legacyCopyReadmeMdToIndexMd` in `techdocs-cli generate` command, and decouple it's logic from the `techdocs-ref` flag. +- d505b7b37d: Fixed issue with git feedback buttons not appearing automatically in docs pages. This was done by appending `repo_url` to the helper function `getRepoUrlFromLocationAnnotation`. +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/integration@1.2.2 + - @backstage/errors@1.1.0 + ## 1.2.0-next.3 ### Patch Changes diff --git a/plugins/techdocs-node/api-report.md b/plugins/techdocs-node/api-report.md index cc9bc8eb51..0ac8c3eaae 100644 --- a/plugins/techdocs-node/api-report.md +++ b/plugins/techdocs-node/api-report.md @@ -217,7 +217,7 @@ export class TechdocsGenerator implements GeneratorBase { config: Config; scmIntegrations: ScmIntegrationRegistry; }); - static readonly defaultDockerImage = 'spotify/techdocs:v1.0.3'; + static readonly defaultDockerImage = 'spotify/techdocs:v1.1.0'; static fromConfig( config: Config, options: GeneratorOptions, diff --git a/plugins/techdocs-node/package.json b/plugins/techdocs-node/package.json index 04f24dca50..d1a79db3b3 100644 --- a/plugins/techdocs-node/package.json +++ b/plugins/techdocs-node/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-node", "description": "Common node.js functionalities for TechDocs, to be shared between techdocs-backend plugin and techdocs-cli", - "version": "1.2.0-next.3", + "version": "1.3.0", "main": "src/index.ts", "types": "src/index.ts", "private": false, @@ -42,12 +42,12 @@ "dependencies": { "@azure/identity": "^2.0.1", "@azure/storage-blob": "^12.5.0", - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/plugin-search-common": "^0.3.6-next.0", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/plugin-search-common": "^1.0.0", "@google-cloud/storage": "^6.0.0", "@trendyol-js/openstack-swift-sdk": "^0.0.5", "@types/express": "^4.17.6", @@ -64,7 +64,7 @@ "winston": "^3.2.1" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/fs-extra": "^9.0.5", "@types/js-yaml": "^4.0.0", "@types/mime-types": "^2.1.0", diff --git a/plugins/techdocs-node/src/stages/generate/helpers.ts b/plugins/techdocs-node/src/stages/generate/helpers.ts index e1a79ecc19..50db0eb86a 100644 --- a/plugins/techdocs-node/src/stages/generate/helpers.ts +++ b/plugins/techdocs-node/src/stages/generate/helpers.ts @@ -101,9 +101,12 @@ export const getRepoUrlFromLocationAnnotation = ( if (locationType === 'url') { const integration = scmIntegrations.byUrl(target); - // We only support it for github and gitlab for now as the edit_uri + // We only support it for github, gitlab and bitbucketServer for now as the edit_uri // is not properly supported for others yet. - if (integration && ['github', 'gitlab'].includes(integration.type)) { + if ( + integration && + ['github', 'gitlab', 'bitbucketServer'].includes(integration.type) + ) { // handle the case where a user manually writes url:https://github.com/backstage/backstage i.e. without /blob/... const { filepathtype } = gitUrlParse(target); if (filepathtype === '') { diff --git a/plugins/techdocs-node/src/stages/generate/techdocs.ts b/plugins/techdocs-node/src/stages/generate/techdocs.ts index e3debab526..d80449d58c 100644 --- a/plugins/techdocs-node/src/stages/generate/techdocs.ts +++ b/plugins/techdocs-node/src/stages/generate/techdocs.ts @@ -53,7 +53,7 @@ export class TechdocsGenerator implements GeneratorBase { * The default docker image (and version) used to generate content. Public * and static so that techdocs-node consumers can use the same version. */ - public static readonly defaultDockerImage = 'spotify/techdocs:v1.0.3'; + public static readonly defaultDockerImage = 'spotify/techdocs:v1.1.0'; private readonly logger: Logger; private readonly containerRunner: ContainerRunner; private readonly options: GeneratorConfig; diff --git a/plugins/techdocs-node/src/stages/publish/awsS3.test.ts b/plugins/techdocs-node/src/stages/publish/awsS3.test.ts index 6372093c4b..1ca9cf2abf 100644 --- a/plugins/techdocs-node/src/stages/publish/awsS3.test.ts +++ b/plugins/techdocs-node/src/stages/publish/awsS3.test.ts @@ -478,7 +478,7 @@ describe('AwsS3Publish', () => { await expect(fails).rejects.toMatchObject({ message: expect.stringMatching( - /TechDocs metadata fetch failed; caused by Error: The file .* does not exist/i, + 'TechDocs metadata fetch failed; caused by Error: Unable to read stream; caused by Error: The file invalid/triplet/path/techdocs_metadata.json does not exist', ), }); }); diff --git a/plugins/techdocs-node/src/stages/publish/awsS3.ts b/plugins/techdocs-node/src/stages/publish/awsS3.ts index e5914d2fdf..12940e0117 100644 --- a/plugins/techdocs-node/src/stages/publish/awsS3.ts +++ b/plugins/techdocs-node/src/stages/publish/awsS3.ts @@ -49,7 +49,9 @@ const streamToBuffer = (stream: Readable): Promise => { try { const chunks: any[] = []; stream.on('data', chunk => chunks.push(chunk)); - stream.on('error', reject); + stream.on('error', (e: Error) => + reject(new ForwardedError('Unable to read stream', e)), + ); stream.on('end', () => resolve(Buffer.concat(chunks))); } catch (e) { throw new ForwardedError('Unable to parse the response data', e); diff --git a/plugins/techdocs-react/CHANGELOG.md b/plugins/techdocs-react/CHANGELOG.md index ffc63b4c01..08db6050b8 100644 --- a/plugins/techdocs-react/CHANGELOG.md +++ b/plugins/techdocs-react/CHANGELOG.md @@ -1,5 +1,49 @@ # @backstage/plugin-techdocs-react +## 1.0.3 + +### Patch Changes + +- 29d6cf0147: Add `toLowerEntityRefMaybe()` helper function for handling `techdocs.legacyUseCaseSensitiveTripletPaths` flag. + Pass modified `entityRef` to `TechDocsReaderPageContext` to handle the `techdocs.legacyUseCaseSensitiveTripletPaths` flag. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 1.0.3-next.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 1.0.3-next.1 + +### Patch Changes + +- 29d6cf0147: Add `toLowerEntityRefMaybe()` helper function for handling `techdocs.legacyUseCaseSensitiveTripletPaths` flag. + Pass modified `entityRef` to `TechDocsReaderPageContext` to handle the `techdocs.legacyUseCaseSensitiveTripletPaths` flag. +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + +## 1.0.3-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 1.0.2 + +### Patch Changes + +- c3cfc83af2: Updated JSDoc to be MDX compatible. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + ## 1.0.2-next.2 ### Patch Changes diff --git a/plugins/techdocs-react/api-report.md b/plugins/techdocs-react/api-report.md index 336481e922..d04b852d07 100644 --- a/plugins/techdocs-react/api-report.md +++ b/plugins/techdocs-react/api-report.md @@ -7,6 +7,7 @@ import { ApiRef } from '@backstage/core-plugin-api'; import { AsyncState } from 'react-use/lib/useAsync'; import { ComponentType } from 'react'; import { CompoundEntityRef } from '@backstage/catalog-model'; +import { Config } from '@backstage/config'; import { Dispatch } from 'react'; import { Entity } from '@backstage/catalog-model'; import { Extension } from '@backstage/core-plugin-api'; @@ -152,6 +153,12 @@ export interface TechDocsStorageApi { // @public export const techdocsStorageApiRef: ApiRef; +// @public +export function toLowercaseEntityRefMaybe( + entityRef: CompoundEntityRef, + config: Config, +): CompoundEntityRef; + // @public export const useShadowDomStylesLoading: (element: Element | null) => boolean; diff --git a/plugins/techdocs-react/package.json b/plugins/techdocs-react/package.json index 6ad4fe4f9c..8074b799bf 100644 --- a/plugins/techdocs-react/package.json +++ b/plugins/techdocs-react/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs-react", "description": "Shared frontend utilities for TechDocs and Addons", - "version": "1.0.2-next.2", + "version": "1.0.3", "private": false, "publishConfig": { "access": "public", @@ -35,9 +35,10 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", + "@backstage/catalog-model": "^1.1.0", + "@backstage/config": "^1.0.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", "@backstage/version-bridge": "^1.0.1", "@material-ui/core": "^4.12.2", "@material-ui/lab": "4.0.0-alpha.57", @@ -56,8 +57,8 @@ "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", - "@backstage/test-utils": "^1.1.2-next.2", - "@backstage/theme": "^0.2.16-next.1" + "@backstage/test-utils": "^1.1.3", + "@backstage/theme": "^0.2.16" }, "files": [ "alpha", diff --git a/plugins/techdocs-react/src/context.test.tsx b/plugins/techdocs-react/src/context.test.tsx index 14669dc336..6cc5537d9e 100644 --- a/plugins/techdocs-react/src/context.test.tsx +++ b/plugins/techdocs-react/src/context.test.tsx @@ -21,6 +21,7 @@ import { ThemeProvider } from '@material-ui/core'; import { lightTheme } from '@backstage/theme'; import { TestApiProvider } from '@backstage/test-utils'; import { Entity, CompoundEntityRef } from '@backstage/catalog-model'; +import { configApiRef } from '@backstage/core-plugin-api'; import { techdocsApiRef } from './api'; import { useTechDocsReaderPage, TechDocsReaderPageProvider } from './context'; @@ -55,6 +56,10 @@ const techdocsApiMock = { getTechDocsMetadata: jest.fn().mockResolvedValue(mockTechDocsMetadata), }; +const configApiMock = { + getOptionalBoolean: jest.fn().mockReturnValue(undefined), +}; + const wrapper = ({ entityRef = { kind: mockEntityMetadata.kind, @@ -67,7 +72,12 @@ const wrapper = ({ children: React.ReactNode; }) => ( - + {children} @@ -123,4 +133,28 @@ describe('useTechDocsReaderPage', () => { '

Shadow DOM Mock

', ); }); + + it('should set entityRef as lowercase when legacyUseCaseSensitiveTripletPaths is false', async () => { + const lowercaseEntityRef = { + kind: mockEntityMetadata.kind.toLocaleLowerCase(), + name: mockEntityMetadata.metadata.name.toLocaleLowerCase(), + namespace: mockEntityMetadata.metadata.namespace?.toLocaleLowerCase(), + }; + const { result } = renderHook(() => useTechDocsReaderPage(), { wrapper }); + + expect(result.current.entityRef).toStrictEqual(lowercaseEntityRef); + }); + + it('entityRef is not modified when legacyUseCaseSensitiveTripletPaths is true', async () => { + configApiMock.getOptionalBoolean.mockReturnValueOnce(true); + const caseSensitiveEntityRef = { + kind: mockEntityMetadata.kind, + name: mockEntityMetadata.metadata.name, + namespace: mockEntityMetadata.metadata.namespace!!, + }; + + const { result } = renderHook(() => useTechDocsReaderPage(), { wrapper }); + + expect(result.current.entityRef).toStrictEqual(caseSensitiveEntityRef); + }); }); diff --git a/plugins/techdocs-react/src/context.tsx b/plugins/techdocs-react/src/context.tsx index 4f2fa26164..66faf858fa 100644 --- a/plugins/techdocs-react/src/context.tsx +++ b/plugins/techdocs-react/src/context.tsx @@ -33,11 +33,13 @@ import { createVersionedValueMap, } from '@backstage/version-bridge'; -import { useApi } from '@backstage/core-plugin-api'; +import { configApiRef, useApi } from '@backstage/core-plugin-api'; import { techdocsApiRef } from './api'; import { TechDocsEntityMetadata, TechDocsMetadata } from './types'; +import { toLowercaseEntityRefMaybe } from './helpers'; + const areEntityRefsEqual = ( prevEntityRef: CompoundEntityRef, nextEntityRef: CompoundEntityRef, @@ -107,6 +109,7 @@ export type TechDocsReaderPageProviderProps = { export const TechDocsReaderPageProvider = memo( ({ entityRef, children }: TechDocsReaderPageProviderProps) => { const techdocsApi = useApi(techdocsApiRef); + const config = useApi(configApiRef); const metadata = useAsync(async () => { return techdocsApi.getTechDocsMetadata(entityRef); @@ -126,7 +129,7 @@ export const TechDocsReaderPageProvider = memo( const value = { metadata, - entityRef, + entityRef: toLowercaseEntityRefMaybe(entityRef, config), entityMetadata, shadowRoot, setShadowRoot, diff --git a/plugins/techdocs-react/src/helpers.ts b/plugins/techdocs-react/src/helpers.ts new file mode 100644 index 0000000000..3f10fff2ba --- /dev/null +++ b/plugins/techdocs-react/src/helpers.ts @@ -0,0 +1,37 @@ +/* + * Copyright 2022 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { Config } from '@backstage/config'; +import { CompoundEntityRef } from '@backstage/catalog-model'; + +/** + * Lower-case entity triplets by default, but allow override. + * + * @public + */ +export function toLowercaseEntityRefMaybe( + entityRef: CompoundEntityRef, + config: Config, +): CompoundEntityRef { + if (config.getOptionalBoolean('techdocs.legacyUseCaseSensitiveTripletPaths')) + return entityRef; + + entityRef.kind = entityRef.kind.toLocaleLowerCase(); + entityRef.name = entityRef.name.toLocaleLowerCase(); + entityRef.namespace = entityRef.namespace.toLocaleLowerCase(); + + return entityRef; +} diff --git a/plugins/techdocs-react/src/index.ts b/plugins/techdocs-react/src/index.ts index bd2edda763..00ba620651 100644 --- a/plugins/techdocs-react/src/index.ts +++ b/plugins/techdocs-react/src/index.ts @@ -51,3 +51,4 @@ export { useShadowRootElements, useShadowRootSelection, } from './hooks'; +export { toLowercaseEntityRefMaybe } from './helpers'; diff --git a/plugins/techdocs/CHANGELOG.md b/plugins/techdocs/CHANGELOG.md index c8b38e5a70..099c84eb0b 100644 --- a/plugins/techdocs/CHANGELOG.md +++ b/plugins/techdocs/CHANGELOG.md @@ -1,5 +1,103 @@ # @backstage/plugin-techdocs +## 1.3.1 + +### Patch Changes + +- e924d2d013: Added back reduction in size, this fixes the extremely large TeachDocs headings +- b86ed4d990: Add highlight to active navigation item and navigation parents. +- 7a98c73dc8: Fixed techdocs sidebar layout bug for medium devices. +- 8acb22205c: Scroll techdocs navigation into focus and expand any nested navigation items. +- Updated dependencies + - @backstage/integration@1.3.0 + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + - @backstage/plugin-techdocs-react@1.0.3 + - @backstage/integration-react@1.1.3 + - @backstage/plugin-search-react@1.0.1 + +## 1.3.1-next.2 + +### Patch Changes + +- 8acb22205c: Scroll techdocs navigation into focus and expand any nested navigation items. +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + - @backstage/integration-react@1.1.3-next.1 + - @backstage/plugin-search-react@1.0.1-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.2 + +## 1.3.1-next.1 + +### Patch Changes + +- b86ed4d990: Add highlight to active navigation item and navigation parents. +- Updated dependencies + - @backstage/core-components@0.10.1-next.1 + - @backstage/integration@1.3.0-next.1 + - @backstage/plugin-techdocs-react@1.0.3-next.1 + - @backstage/plugin-catalog-react@1.1.3-next.1 + +## 1.3.1-next.0 + +### Patch Changes + +- 7a98c73dc8: Fixed techdocs sidebar layout bug for medium devices. +- Updated dependencies + - @backstage/integration@1.3.0-next.0 + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/integration-react@1.1.3-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + - @backstage/plugin-search-react@1.0.1-next.0 + - @backstage/plugin-techdocs-react@1.0.3-next.0 + +## 1.3.0 + +### Minor Changes + +- ebf3eb1641: Use the same initial filter `owned` for the `TechDocsIndexPage` as for the `CatalogPage`. + + If you prefer to keep the previous behavior, you can change the default for the initial filter + to `all` (or `starred` if you rather prefer that). + + ``` + + ``` + + In general, with this change you will be able to set props at `TechDocsIndexPage`. + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- e2d7b76f43: Upgrade git-url-parse to 12.0.0. + + Motivation for upgrade is transitively upgrading parse-url which is vulnerable + to several CVEs detected by Snyk. + + - SNYK-JS-PARSEURL-2935944 + - SNYK-JS-PARSEURL-2935947 + - SNYK-JS-PARSEURL-2936249 + +- 3cbebf710e: Reorder browser tab title in Techdocs pages to have the site name first. +- 726577958f: Remove the 60% factor from the font size calculation of headers to use the exact size defined in BackstageTheme. +- 7739141ab2: Fix: When docs are shown in an entity page under the docs tab the sidebars start overlapping with the header and tabs in the page when you scroll the documentation content. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/plugin-techdocs-react@1.0.2 + - @backstage/plugin-search-react@1.0.0 + - @backstage/plugin-search-common@1.0.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/integration@1.2.2 + - @backstage/integration-react@1.1.2 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 1.2.1-next.3 ### Patch Changes diff --git a/plugins/techdocs/api-report.md b/plugins/techdocs/api-report.md index 9a6c902f61..b2f0331a9b 100644 --- a/plugins/techdocs/api-report.md +++ b/plugins/techdocs/api-report.md @@ -291,6 +291,7 @@ const techdocsPlugin: BackstagePlugin< }>; entityContent: RouteRef; }, + {}, {} >; export { techdocsPlugin as plugin }; @@ -344,11 +345,7 @@ export type TechDocsReaderPageProps = { }; // @public -export type TechDocsReaderPageRenderFunction = ({ - techdocsMetadataValue, - entityMetadataValue, - entityRef, -}: { +export type TechDocsReaderPageRenderFunction = (options: { techdocsMetadataValue?: TechDocsMetadata_2 | undefined; entityMetadataValue?: TechDocsEntityMetadata_2 | undefined; entityRef: CompoundEntityRef; @@ -356,10 +353,8 @@ export type TechDocsReaderPageRenderFunction = ({ }) => JSX.Element; // @public -export const TechDocsReaderPageSubheader: ({ - toolbarProps, -}: { - toolbarProps?: ToolbarProps<'div', {}> | undefined; +export const TechDocsReaderPageSubheader: (props: { + toolbarProps?: ToolbarProps; }) => JSX.Element | null; // @public diff --git a/plugins/techdocs/package.json b/plugins/techdocs/package.json index 79c575b566..8055a20009 100644 --- a/plugins/techdocs/package.json +++ b/plugins/techdocs/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-techdocs", "description": "The Backstage plugin that renders technical documentation for your components", - "version": "1.2.1-next.3", + "version": "1.3.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -35,18 +35,18 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", - "@backstage/integration-react": "^1.1.2-next.3", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/plugin-search-common": "^0.3.6-next.0", - "@backstage/plugin-search-react": "^0.2.2-next.3", - "@backstage/plugin-techdocs-react": "^1.0.2-next.2", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", + "@backstage/integration-react": "^1.1.3", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/plugin-search-common": "^1.0.0", + "@backstage/plugin-search-react": "^1.0.1", + "@backstage/plugin-techdocs-react": "^1.0.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -67,10 +67,10 @@ "react-dom": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/react-hooks": "^8.0.0", @@ -81,7 +81,7 @@ "@types/node": "^16.11.26", "canvas": "^2.6.1", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist", diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPage/context.test.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPage/context.test.tsx index 148b740205..2380724960 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPage/context.test.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPage/context.test.tsx @@ -22,6 +22,7 @@ import { ThemeProvider } from '@material-ui/core'; import { lightTheme } from '@backstage/theme'; import { TestApiProvider } from '@backstage/test-utils'; import { Entity, CompoundEntityRef } from '@backstage/catalog-model'; +import { configApiRef } from '@backstage/core-plugin-api'; import { techdocsApiRef, TechDocsMetadata, @@ -52,6 +53,10 @@ const techdocsApiMock = { getTechDocsMetadata: jest.fn().mockResolvedValue(mockTechDocsMetadata), }; +const configApiMock = { + getOptionalBoolean: jest.fn().mockReturnValue(undefined), +}; + const wrapper = ({ entityRef = { kind: mockEntityMetadata.kind, @@ -64,7 +69,12 @@ const wrapper = ({ children: React.ReactNode; }) => ( - + {children} diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/dom.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/dom.tsx index 76b07c9d32..98bd6d867c 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/dom.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageContent/dom.tsx @@ -41,6 +41,7 @@ import { rewriteDocLinks, simplifyMkdocsFooter, scrollIntoAnchor, + scrollIntoNavigation, transform as transformer, copyToClipboard, useSanitizerTransformer, @@ -166,6 +167,7 @@ export const useTechDocsReaderDom = ( async (transformedElement: Element) => transformer(transformedElement, [ scrollIntoAnchor(), + scrollIntoNavigation(), copyToClipboard(theme), addLinkClickListener({ baseUrl: window.location.origin, diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx index 8826154eee..e76cb1d173 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageHeader/TechDocsReaderPageHeader.tsx @@ -77,16 +77,13 @@ export const TechDocsReaderPageHeader = ( useEffect(() => { if (!metadata) return; - setTitle(prevTitle => { - const { site_name } = metadata; - return prevTitle || site_name; - }); - setSubtitle(prevSubtitle => { + setTitle(metadata.site_name); + setSubtitle(() => { let { site_description } = metadata; if (!site_description || site_description === 'None') { site_description = 'Home'; } - return prevSubtitle || site_description; + return site_description; }); }, [metadata, setTitle, setSubtitle]); diff --git a/plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx b/plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx index a0013e81ab..0cef4d521f 100644 --- a/plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx +++ b/plugins/techdocs/src/reader/components/TechDocsReaderPageSubheader/TechDocsReaderPageSubheader.tsx @@ -47,9 +47,7 @@ const useStyles = makeStyles(theme => ({ * Please use the Tech Docs add-ons to customize it * @public */ -export const TechDocsReaderPageSubheader = ({ - toolbarProps, -}: { +export const TechDocsReaderPageSubheader = (props: { toolbarProps?: ToolbarProps; }) => { const classes = useStyles(); @@ -81,7 +79,7 @@ export const TechDocsReaderPageSubheader = ({ if (entityMetadataLoading === false && !entityMetadata) return null; return ( - + { + afterEach(() => { + jest.clearAllMocks(); + }); + + it('scroll to active navigation item', async () => { + await createTestShadowDom(FIXTURES.FIXTURE_STANDARD_PAGE, { + preTransformers: [], + postTransformers: [scrollIntoNavigation()], + }); + + // jsdom does not implement scrollIntoView so we attach a function to the + // prototype to be able to test the expected behaviour. + const scrollNavIntoView = jest.fn(); + window.HTMLElement.prototype.scrollIntoView = scrollNavIntoView; + + jest.advanceTimersByTime(200); + + expect(scrollNavIntoView).toHaveBeenCalledWith(); + }); + + it('expand active navigation items', async () => { + const shadowDom = await createTestShadowDom( + FIXTURES.FIXTURE_STANDARD_PAGE, + { + preTransformers: [], + postTransformers: [scrollIntoNavigation()], + }, + ); + + // jsdom does not implement scrollIntoView so we attach an empty function to + // support the behaviour. + window.HTMLElement.prototype.scrollIntoView = () => {}; + + const click = jest.fn(); + shadowDom.addEventListener('click', click); + + jest.advanceTimersByTime(200); + + expect(click).toHaveBeenCalled(); + }); + + it('does not expand already expanded active navigation items', async () => { + const shadowDom = await createTestShadowDom( + FIXTURES.FIXTURE_STANDARD_PAGE_EXPANDED_NAVIGATION, + { + preTransformers: [], + postTransformers: [scrollIntoNavigation()], + }, + ); + + // jsdom does not implement scrollIntoView so we attach an empty function to + // support the behaviour. + window.HTMLElement.prototype.scrollIntoView = () => {}; + + const click = jest.fn(); + shadowDom.addEventListener('click', click); + + jest.advanceTimersByTime(200); + + expect(click).not.toHaveBeenCalled(); + }); +}); diff --git a/plugins/techdocs/src/reader/transformers/scrollIntoNavigation.ts b/plugins/techdocs/src/reader/transformers/scrollIntoNavigation.ts new file mode 100644 index 0000000000..e8d6161404 --- /dev/null +++ b/plugins/techdocs/src/reader/transformers/scrollIntoNavigation.ts @@ -0,0 +1,38 @@ +/* + * Copyright 2021 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import type { Transformer } from './transformer'; + +export const scrollIntoNavigation = (): Transformer => { + return dom => { + setTimeout(() => { + const activeNavItems = dom?.querySelectorAll(`li.md-nav__item--active`); + if (activeNavItems.length !== 0) { + // expand all navigation items that are active + activeNavItems.forEach(activeNavItem => { + const checkbox = activeNavItem?.querySelector('input'); + if (!checkbox?.checked) { + checkbox?.click(); + } + }); + + const lastItem = activeNavItems[activeNavItems.length - 1]; + lastItem.scrollIntoView(); + } + }, 200); + return dom; + }; +}; diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts index 2488504dd9..c4e6938fdc 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/layout.ts @@ -16,6 +16,8 @@ import { RuleOptions } from './types'; +const SIDEBAR_WIDTH = '224px'; + export default ({ theme, sidebar }: RuleOptions) => ` /*================== Layout ==================*/ @@ -47,6 +49,11 @@ export default ({ theme, sidebar }: RuleOptions) => ` height: 20px !important; } +.md-nav__item--active > .md-nav__link, a.md-nav__link--active { + text-decoration: underline; + color: var(--md-typeset-a-color); +} + .md-main__inner { margin-top: 0; } @@ -61,7 +68,7 @@ export default ({ theme, sidebar }: RuleOptions) => ` scrollbar-width: thin; } .md-sidebar .md-sidebar__scrollwrap { - width: calc(16rem - 10px); + width: calc(12.1rem); } .md-sidebar--secondary { right: ${theme.spacing(3)}px; @@ -169,7 +176,9 @@ export default ({ theme, sidebar }: RuleOptions) => ` width: 12.1rem !important; z-index: 200; left: ${ - sidebar.isPinned ? 'calc(-12.1rem + 242px)' : 'calc(-12.1rem + 72px)' + sidebar.isPinned + ? `calc(-12.1rem + ${SIDEBAR_WIDTH})` + : 'calc(-12.1rem + 72px)' } !important; } .md-sidebar--secondary:not([hidden]) { diff --git a/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts b/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts index 6a3b0461ef..4c1eef1ea4 100644 --- a/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts +++ b/plugins/techdocs/src/reader/transformers/styles/rules/typeset.ts @@ -47,7 +47,8 @@ ${headings.reduce((style, heading) => { let factor: number | string = 1; if (typeof value === 'number') { // convert px to rem - factor = value / htmlFontSize; + // 60% of the size defined because it is too big + factor = (value / htmlFontSize) * 0.6; } if (typeof value === 'string') { factor = value.replace('rem', ''); diff --git a/plugins/techdocs/src/test-utils/fixtures/mkdocs-expanded-index.ts b/plugins/techdocs/src/test-utils/fixtures/mkdocs-expanded-index.ts new file mode 100644 index 0000000000..1d607fd8b4 --- /dev/null +++ b/plugins/techdocs/src/test-utils/fixtures/mkdocs-expanded-index.ts @@ -0,0 +1,1577 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +export default ` + + + + + + + + + + + + + + + MkDocs + + + + + + + + + + + + + + + + +
+ +
+ +
+ +
+
+
+
+
+
+ +
+
+
+ + + +
+
+

+ MkDocs +

+

Project documentation with Markdown.

+
+

+ Overview +

+

+ MkDocs is a fast, simple and + downright gorgeous static site generator that's + geared towards building project documentation. Documentation + source files are written in Markdown, and configured with a + single YAML configuration file. Start by reading the + introduction below, then check the User Guide for more info. +

+

+ Host anywhere +

+

+ MkDocs builds completely static HTML sites that you can host on + GitHub pages, Amazon S3, or + anywhere else you + choose. +

+

+ Great themes available +

+

+ There's a stack of good looking + themes available for + MkDocs. Choose between the built in themes: + mkdocs and + readthedocs, select one of the 3rd party themes listed on the + MkDocs Themes + wiki page, or + build your own. +

+

+ Preview your site as you work +

+

+ The built-in dev-server allows you to preview your documentation + as you're writing it. It will even auto-reload and refresh your + browser whenever you save your changes. +

+

+ Easy to customize +

+

+ Get your project documentation looking just the way you want it + by customizing the + theme and/or + installing some plugins. +

+
+

+ Installation +

+

+ Install with a Package Manager +

+

+ If you have and use a package manager (such as + apt-get, + dnf, homebrew, + yum, + chocolatey, etc.) to + install packages on your system, then you may want to search for + a "MkDocs" package and, if a recent version is available, + install it with your package manager (check your system's + documentation for details). That's it, you're done! Skip down to + Getting Started. +

+

+ If your package manager does not have a recent "MkDocs" package, + you can still use your package manager to install "Python" and + "pip". Then you can use pip to + install MkDocs. +

+

+ Manual Installation +

+

+ In order to manually install MkDocs you'll need + Python installed on your + system, as well as the Python package manager, + pip. You can check if you have these already installed from the + command line: +

+
+
$ python --version
+Python 3.8.2
+$ pip --version
+pip 20.0.2 from /usr/local/lib/python3.8/site-packages/pip (python 3.8)
+
+
+ +

+ MkDocs supports Python versions 3.5, 3.6, 3.7, 3.8, and pypy3. +

+

+ Installing Python +

+

+ Install Python by + downloading an installer appropriate for your system from + python.org and + running it. +

+
+

Note

+

+ If you are installing Python on Windows, be sure to check the + box to have Python added to your PATH if the installer offers + such an option (it's normally off by default). +

+

+ Add Python to PATH +

+
+

+ Installing pip +

+

+ If you're using a recent version of Python, the Python package + manager, + pip, is most likely installed by default. However, you may need to + upgrade pip to the lasted version: +

+
+
pip install --upgrade pip
+
+
+ +

+ If you need to install + pip + for the first time, download + get-pip.py. + Then run the following command to install it: +

+
+
python get-pip.py
+
+
+ +

+ Installing MkDocs +

+

Install the mkdocs package using pip:

+
+
pip install mkdocs
+
+
+ +

+ You should now have the mkdocs command installed on + your system. Run mkdocs --version to check that + everything worked okay. +

+
+
$ mkdocs --version
+mkdocs, version 0.15.3
+
+
+ +
+

Note

+

+ If you would like manpages installed for MkDocs, the + click-man + tool can generate and install them for you. Simply run the + following two commands: +

+
+ + + + +
+
+
+1
+2
+
+
+
+
pip install click-man
+click-man --target path/to/man/pages mkdocs
+
+
+
+ +

+ See the + click-man documentation + for an explanation of why manpages are not automatically + generated and installed by pip. +

+ +
+

Note

+

+ If you are using Windows, some of the above commands may not + work out-of-the-box. +

+

+ A quick solution may be to preface every Python command with + python -m like this: +

+ + + + + +
+
+
+1
+2
+
+
+
+
python -m pip install mkdocs
+python -m mkdocs
+
+
+
+ +

+ For a more permanent solution, you may need to edit your + PATH environment variable to include the + Scripts directory of your Python installation. + Recent versions of Python include a script to do this for you. + Navigate to your Python installation directory (for example + C:\Python38\), open the Tools, then + Scripts folder, and run the + win_add2path.py file by double clicking on it. + Alternatively, you can + download + the script and run it (python win_add2path.py). +

+
+
+

+ Getting Started +

+

Getting started is super easy.

+
+
mkdocs new my-project
+cd my-project
+
+
+ +

+ Take a moment to review the initial project that has been + created for you. +

+

+ The initial MkDocs layout +

+

+ There's a single configuration file named + mkdocs.yml, and a folder named + docs that will contain your documentation source + files. Right now the docs folder just contains a + single documentation page, named index.md. +

+

+ MkDocs comes with a built-in dev-server that lets you preview + your documentation as you work on it. Make sure you're in the + same directory as the mkdocs.yml configuration + file, and then start the server by running the + mkdocs serve command: +

+
+
$ mkdocs serve
+INFO    -  Building documentation...
+INFO    -  Cleaning site directory
+[I 160402 15:50:43 server:271] Serving on http://127.0.0.1:8000
+[I 160402 15:50:43 handlers:58] Start watching changes
+[I 160402 15:50:43 handlers:60] Start detecting changes
+
+
+ +

+ Open up http://127.0.0.1:8000/ in your browser, and + you'll see the default home page being displayed: +

+

+ The MkDocs live server +

+

+ The dev-server also supports auto-reloading, and will rebuild + your documentation whenever anything in the configuration file, + documentation directory, or theme directory changes. +

+

+ Open the docs/index.md document in your text editor + of choice, change the initial heading to MkLorum, + and save your changes. Your browser will auto-reload and you + should see your updated documentation immediately. +

+

+ Now try editing the configuration file: mkdocs.yml. + Change the + site_name + setting to MkLorum and save the file. +

+
+
site_name: MkLorum
+
+
+ +

+ Your browser should immediately reload, and you'll see your new + site name take effect. +

+

The site_name setting

+

+ Adding pages +

+

Now add a second page to your documentation:

+
+
curl 'https://jaspervdj.be/lorem-markdownum/markdown.txt' > docs/about.md
+
+
+ +

+ As our documentation site will include some navigation headers, + you may want to edit the configuration file and add some + information about the order, title, and nesting of each page in + the navigation header by adding a + nav + setting: +

+
+
site_name: MkLorum
+nav:
+    - Home: index.md
+    - About: about.md
+
+
+ +

+ Save your changes and you'll now see a navigation bar with + Home and About items on the left as + well as Search, Previous, and + Next items on the right. +

+

Screenshot

+

+ Try the menu items and navigate back and forth between pages. + Then click on Search. A search dialog will appear, + allowing you to search for any text on any page. Notice that the + search results include every occurrence of the search term on + the site and links directly to the section of the page in which + the search term appears. You get all of that with no effort or + configuration on your part! +

+

Screenshot

+

+ Theming our documentation +

+

+ Now change the configuration file to alter how the documentation + is displayed by changing the theme. Edit the + mkdocs.yml file and add a + theme + setting: +

+
+
site_name: MkLorum
+nav:
+    - Home: index.md
+    - About: about.md
+theme: readthedocs
+
+
+ +

+ Save your changes, and you'll see the ReadTheDocs theme being + used. +

+

Screenshot

+

+ Changing the Favicon Icon +

+

+ By default, MkDocs uses the + MkDocs favicon icon. To use a + different icon, create an img subdirectory in your + docs_dir and copy your custom + favicon.ico file to that directory. MkDocs will + automatically detect and use that file as your favicon icon. +

+

+ Building the site +

+

+ That's looking good. You're ready to deploy the first pass of + your MkLorum documentation. First build the + documentation: +

+
+
mkdocs build
+
+
+ +

+ This will create a new directory, named site. Take + a look inside the directory: +

+
+
$ ls site
+about  fonts  index.html  license  search.html
+css    img    js          mkdocs   sitemap.xml
+
+
+ +

+ Notice that your source documentation has been output as two + HTML files named index.html and + about/index.html. You also have various other media + that's been copied into the site directory as part + of the documentation theme. You even have a + sitemap.xml file and + mkdocs/search_index.json. +

+

+ If you're using source code control such as git you + probably don't want to check your documentation builds into the + repository. Add a line containing site/ to your + .gitignore file. +

+
+
echo "site/" >> .gitignore
+
+
+ +

+ If you're using another source code control tool you'll want to + check its documentation on how to ignore specific directories. +

+

+ After some time, files may be removed from the documentation but + they will still reside in the site directory. To + remove those stale files, just run mkdocs with the + --clean switch. +

+
+
mkdocs build --clean
+
+
+ +

+ Other Commands and Options +

+

+ There are various other commands and options available. For a + complete list of commands, use the --help flag: +

+
+
mkdocs --help
+
+
+ +

+ To view a list of options available on a given command, use the + --help flag with that command. For example, to get + a list of all options available for the + build command run the following: +

+
+
mkdocs build --help
+
+
+ +

+ Deploying +

+

+ The documentation site that you just built only uses static + files so you'll be able to host it from pretty much anywhere. + GitHub project pages + and + Amazon S3 + may be good hosting options, depending upon your needs. Upload + the contents of the entire site directory to + wherever you're hosting your website from and you're done. For + specific instructions on a number of common hosts, see the + Deploying your Docs + page. +

+

+ Getting help +

+

+ To get help with MkDocs, please use the + discussion group, + GitHub issues + or the MkDocs IRC channel #mkdocs on freenode. +

+ + + + + + + + + + + + + + + +`; diff --git a/plugins/techdocs/src/test-utils/index.ts b/plugins/techdocs/src/test-utils/index.ts index 584934f732..3ed7161f01 100644 --- a/plugins/techdocs/src/test-utils/index.ts +++ b/plugins/techdocs/src/test-utils/index.ts @@ -15,9 +15,11 @@ */ import FIXTURE_STANDARD_PAGE from './fixtures/mkdocs-index'; +import FIXTURE_STANDARD_PAGE_EXPANDED_NAVIGATION from './fixtures/mkdocs-expanded-index'; export const FIXTURES = { FIXTURE_STANDARD_PAGE, + FIXTURE_STANDARD_PAGE_EXPANDED_NAVIGATION, }; export * from './shadowDom'; diff --git a/plugins/techdocs/src/types.ts b/plugins/techdocs/src/types.ts index 014bf0d090..c07f7c3907 100644 --- a/plugins/techdocs/src/types.ts +++ b/plugins/techdocs/src/types.ts @@ -25,11 +25,7 @@ import { * * @public */ -export type TechDocsReaderPageRenderFunction = ({ - techdocsMetadataValue, - entityMetadataValue, - entityRef, -}: { +export type TechDocsReaderPageRenderFunction = (options: { techdocsMetadataValue?: TechDocsMetadata | undefined; entityMetadataValue?: TechDocsEntityMetadata | undefined; entityRef: CompoundEntityRef; diff --git a/plugins/todo-backend/CHANGELOG.md b/plugins/todo-backend/CHANGELOG.md index 285c9c463c..bfeaef7f11 100644 --- a/plugins/todo-backend/CHANGELOG.md +++ b/plugins/todo-backend/CHANGELOG.md @@ -1,5 +1,34 @@ # @backstage/plugin-todo-backend +## 0.1.32 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/integration@1.3.0 + +## 0.1.32-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/integration@1.3.0-next.0 + +## 0.1.31 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/catalog-model@1.1.0 + - @backstage/integration@1.2.2 + - @backstage/catalog-client@1.0.4 + - @backstage/errors@1.1.0 + ## 0.1.31-next.2 ### Patch Changes diff --git a/plugins/todo-backend/package.json b/plugins/todo-backend/package.json index b25fc3e41a..b6eda27164 100644 --- a/plugins/todo-backend/package.json +++ b/plugins/todo-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo-backend", "description": "A Backstage backend plugin that lets you browse TODO comments in your source code", - "version": "0.1.31-next.2", + "version": "0.1.32", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -29,12 +29,12 @@ "start": "backstage-cli package start" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/catalog-client": "^1.0.4-next.2", - "@backstage/catalog-model": "^1.1.0-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/catalog-client": "^1.0.4", + "@backstage/catalog-model": "^1.1.0", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/integration": "^1.2.2-next.3", + "@backstage/errors": "^1.1.0", + "@backstage/integration": "^1.3.0", "@types/express": "^4.17.6", "express": "^4.17.1", "express-promise-router": "^4.1.0", @@ -43,9 +43,9 @@ "yn": "^4.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/supertest": "^2.0.8", - "msw": "^0.44.0", + "msw": "^0.45.0", "supertest": "^6.1.3" }, "files": [ diff --git a/plugins/todo/CHANGELOG.md b/plugins/todo/CHANGELOG.md index d9dde02575..ae2fe2a9df 100644 --- a/plugins/todo/CHANGELOG.md +++ b/plugins/todo/CHANGELOG.md @@ -1,5 +1,45 @@ # @backstage/plugin-todo +## 0.2.10 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.2.10-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.2.10-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.2.9 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.2.9-next.3 ### Patch Changes diff --git a/plugins/todo/api-report.md b/plugins/todo/api-report.md index c1667f1111..09356cd48f 100644 --- a/plugins/todo/api-report.md +++ b/plugins/todo/api-report.md @@ -84,6 +84,7 @@ export const todoPlugin: BackstagePlugin< { entityContent: RouteRef; }, + {}, {} >; ``` diff --git a/plugins/todo/package.json b/plugins/todo/package.json index f0412472b1..48c8c603a4 100644 --- a/plugins/todo/package.json +++ b/plugins/todo/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-todo", "description": "A Backstage plugin that lets you browse TODO comments in your source code", - "version": "0.2.9-next.3", + "version": "0.2.10", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -30,12 +30,12 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -45,17 +45,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0", + "msw": "^0.45.0", "react-router": "6.0.0-beta.0" }, "files": [ diff --git a/plugins/user-settings/CHANGELOG.md b/plugins/user-settings/CHANGELOG.md index b833b0323a..25fc8a11d6 100644 --- a/plugins/user-settings/CHANGELOG.md +++ b/plugins/user-settings/CHANGELOG.md @@ -1,5 +1,39 @@ # @backstage/plugin-user-settings +## 0.4.7 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.4.7-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.4.7-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.4.6 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + ## 0.4.6-next.3 ### Patch Changes diff --git a/plugins/user-settings/api-report.md b/plugins/user-settings/api-report.md index a38b37846a..d6aca3c46f 100644 --- a/plugins/user-settings/api-report.md +++ b/plugins/user-settings/api-report.md @@ -20,7 +20,7 @@ import { SessionApi } from '@backstage/core-plugin-api'; // @public (undocumented) export const DefaultProviderSettings: ({ configuredProviders, -}: Props_3) => JSX.Element; +}: Props_2) => JSX.Element; // Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ProviderSettingsItem" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -31,13 +31,10 @@ export const ProviderSettingsItem: ({ description, icon: Icon, apiRef, -}: Props_4) => JSX.Element; +}: Props_3) => JSX.Element; -// Warning: (ae-forgotten-export) The symbol "Props" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "SettingsPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// // @public (undocumented) -export const Router: ({ providerSettings }: Props) => JSX.Element; +export const Router: (props: { providerSettings?: JSX.Element }) => JSX.Element; // Warning: (ae-forgotten-export) The symbol "SettingsProps" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "Settings" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) @@ -59,7 +56,7 @@ export const UserSettingsAppearanceCard: () => JSX.Element; // @public (undocumented) export const UserSettingsAuthProviders: ({ providerSettings, -}: Props_2) => JSX.Element; +}: Props) => JSX.Element; // Warning: (ae-missing-release-tag) "UserSettingsFeatureFlags" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // @@ -84,9 +81,7 @@ export const UserSettingsMenu: () => JSX.Element; // Warning: (ae-missing-release-tag) "UserSettingsPage" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const UserSettingsPage: ({ - providerSettings, -}: { +export const UserSettingsPage: (props: { providerSettings?: JSX.Element | undefined; }) => JSX.Element; @@ -102,6 +97,7 @@ const userSettingsPlugin: BackstagePlugin< { settingsPage: RouteRef; }, + {}, {} >; export { userSettingsPlugin as plugin }; @@ -116,7 +112,7 @@ export const UserSettingsProfileCard: () => JSX.Element; // Warning: (ae-missing-release-tag) "UserSettingsSignInAvatar" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) -export const UserSettingsSignInAvatar: ({ size }: Props_5) => JSX.Element; +export const UserSettingsSignInAvatar: ({ size }: Props_4) => JSX.Element; // @public export const UserSettingsTab: (props: UserSettingsTabProps) => JSX.Element; diff --git a/plugins/user-settings/package.json b/plugins/user-settings/package.json index 5d0c083531..0bc05c1215 100644 --- a/plugins/user-settings/package.json +++ b/plugins/user-settings/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-user-settings", "description": "A Backstage plugin that provides a settings page", - "version": "0.4.6-next.3", + "version": "0.4.7", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,9 +34,9 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -48,17 +48,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/user-settings/src/components/SettingsPage.tsx b/plugins/user-settings/src/components/SettingsPage.tsx index dcaf62d435..9803bf4761 100644 --- a/plugins/user-settings/src/components/SettingsPage.tsx +++ b/plugins/user-settings/src/components/SettingsPage.tsx @@ -28,11 +28,11 @@ import { UserSettingsFeatureFlags } from './FeatureFlags'; import { UserSettingsGeneral } from './General'; import { USER_SETTINGS_TAB_KEY, UserSettingsTabProps } from './UserSettingsTab'; -type Props = { - providerSettings?: JSX.Element; -}; - -export const SettingsPage = ({ providerSettings }: Props) => { +/** + * @public + */ +export const SettingsPage = (props: { providerSettings?: JSX.Element }) => { + const { providerSettings } = props; const { isMobile } = useSidebarPinState(); const outlet = useOutlet(); diff --git a/plugins/vault-backend/CHANGELOG.md b/plugins/vault-backend/CHANGELOG.md index c159aa9ca8..64c3782f9d 100644 --- a/plugins/vault-backend/CHANGELOG.md +++ b/plugins/vault-backend/CHANGELOG.md @@ -1,5 +1,40 @@ # @backstage/plugin-vault-backend +## 0.2.1 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0 + - @backstage/backend-test-utils@0.1.27 + - @backstage/backend-tasks@0.3.4 + +## 0.2.1-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/backend-common@0.15.0-next.0 + - @backstage/backend-tasks@0.3.4-next.0 + - @backstage/backend-test-utils@0.1.27-next.0 + +## 0.2.0 + +### Minor Changes + +- 5ebf2c7023: Throw exceptions instead of swallow them, remove some exported types from the `api-report`, small changes in the API responses & expose the vault `baseUrl` to the frontend as well + +### Patch Changes + +- 7ee4abdcc9: Added a path notion in addition to secret name to allow to differentiate secrets in sub-paths +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/backend-common@0.14.1 + - @backstage/backend-test-utils@0.1.26 + - @backstage/backend-tasks@0.3.3 + - @backstage/errors@1.1.0 + ## 0.2.0-next.3 ### Patch Changes diff --git a/plugins/vault-backend/api-report.md b/plugins/vault-backend/api-report.md index d2e9e1b177..2b1fb14bd0 100644 --- a/plugins/vault-backend/api-report.md +++ b/plugins/vault-backend/api-report.md @@ -48,7 +48,7 @@ export type VaultBuilderReturn = { // @public export class VaultClient implements VaultApi { - constructor({ config }: { config: Config }); + constructor(options: { config: Config }); // (undocumented) getFrontendSecretsUrl(): string; // (undocumented) diff --git a/plugins/vault-backend/package.json b/plugins/vault-backend/package.json index e0172dc803..feca26cd6c 100644 --- a/plugins/vault-backend/package.json +++ b/plugins/vault-backend/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault-backend", "description": "A Backstage backend plugin that integrates towards Vault", - "version": "0.2.0-next.3", + "version": "0.2.1", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,11 +34,11 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/backend-common": "^0.14.1-next.3", - "@backstage/backend-tasks": "^0.3.3-next.3", - "@backstage/backend-test-utils": "^0.1.26-next.3", + "@backstage/backend-common": "^0.15.0", + "@backstage/backend-tasks": "^0.3.4", + "@backstage/backend-test-utils": "^0.1.27", "@backstage/config": "^1.0.1", - "@backstage/errors": "^1.1.0-next.0", + "@backstage/errors": "^1.1.0", "@types/express": "*", "compression": "^1.7.4", "cors": "^2.8.5", @@ -51,10 +51,10 @@ "yn": "^5.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", + "@backstage/cli": "^0.18.1", "@types/compression": "^1.7.2", "@types/supertest": "^2.0.8", - "msw": "^0.44.0", + "msw": "^0.45.0", "supertest": "^6.1.6" }, "files": [ diff --git a/plugins/vault-backend/src/service/vaultApi.ts b/plugins/vault-backend/src/service/vaultApi.ts index 158778294a..16aa39ae03 100644 --- a/plugins/vault-backend/src/service/vaultApi.ts +++ b/plugins/vault-backend/src/service/vaultApi.ts @@ -79,8 +79,8 @@ export class VaultClient implements VaultApi { private vaultConfig: VaultConfig; private readonly limit = plimit(5); - constructor({ config }: { config: Config }) { - this.vaultConfig = getVaultConfig(config); + constructor(options: { config: Config }) { + this.vaultConfig = getVaultConfig(options.config); } private async callApi( diff --git a/plugins/vault/CHANGELOG.md b/plugins/vault/CHANGELOG.md index 219c8e1474..1cbc985e1c 100644 --- a/plugins/vault/CHANGELOG.md +++ b/plugins/vault/CHANGELOG.md @@ -1,5 +1,47 @@ # @backstage/plugin-vault +## 0.1.2 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + - @backstage/plugin-catalog-react@1.1.3 + +## 0.1.2-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/plugin-catalog-react@1.1.3-next.2 + - @backstage/core-components@0.11.0-next.2 + +## 0.1.2-next.0 + +### Patch Changes + +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/plugin-catalog-react@1.1.3-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.1.1 + +### Patch Changes + +- 7ee4abdcc9: Added a path notion in addition to secret name to allow to differentiate secrets in sub-paths +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- 5ebf2c7023: Export missing parameters and added them to the api-report. Also adapted the API to the expected response from the backend +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/catalog-model@1.1.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/plugin-catalog-react@1.1.2 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.1.1-next.3 ### Patch Changes diff --git a/plugins/vault/api-report.md b/plugins/vault/api-report.md index b347989800..8c4e5da829 100644 --- a/plugins/vault/api-report.md +++ b/plugins/vault/api-report.md @@ -27,7 +27,7 @@ export interface VaultApi { export const vaultApiRef: ApiRef; // @public -export const vaultPlugin: BackstagePlugin<{}, {}>; +export const vaultPlugin: BackstagePlugin<{}, {}, {}>; // @public export type VaultSecret = { diff --git a/plugins/vault/package.json b/plugins/vault/package.json index 3364323e13..a50d5c64ca 100644 --- a/plugins/vault/package.json +++ b/plugins/vault/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-vault", "description": "A Backstage plugin that integrates towards Vault", - "version": "0.1.1-next.3", + "version": "0.1.2", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -34,12 +34,12 @@ "postpack": "backstage-cli package postpack" }, "dependencies": { - "@backstage/catalog-model": "^1.1.0-next.3", - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/plugin-catalog-react": "^1.1.2-next.3", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/catalog-model": "^1.1.0", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/plugin-catalog-react": "^1.1.3", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "^4.0.0-alpha.57", @@ -49,17 +49,17 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "*", "@types/node": "*", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/plugins/xcmetrics/CHANGELOG.md b/plugins/xcmetrics/CHANGELOG.md index 3af3a33967..2639b124e8 100644 --- a/plugins/xcmetrics/CHANGELOG.md +++ b/plugins/xcmetrics/CHANGELOG.md @@ -1,5 +1,43 @@ # @backstage/plugin-xcmetrics +## 0.2.28 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-components@0.11.0 + - @backstage/core-plugin-api@1.0.5 + +## 0.2.28-next.1 + +### Patch Changes + +- Updated dependencies + - @backstage/core-components@0.11.0-next.2 + +## 0.2.28-next.0 + +### Patch Changes + +- 29f782eb37: Updated dependency `@types/luxon` to `^3.0.0`. +- Updated dependencies + - @backstage/core-plugin-api@1.0.5-next.0 + - @backstage/core-components@0.10.1-next.0 + +## 0.2.27 + +### Patch Changes + +- a70869e775: Updated dependency `msw` to `^0.43.0`. +- 4e9a90e307: Updated dependency `luxon` to `^3.0.0`. +- 8006d0f9bf: Updated dependency `msw` to `^0.44.0`. +- Updated dependencies + - @backstage/core-components@0.10.0 + - @backstage/core-plugin-api@1.0.4 + - @backstage/theme@0.2.16 + - @backstage/errors@1.1.0 + ## 0.2.27-next.3 ### Patch Changes diff --git a/plugins/xcmetrics/api-report.md b/plugins/xcmetrics/api-report.md index 3e2aa23451..373748e9e2 100644 --- a/plugins/xcmetrics/api-report.md +++ b/plugins/xcmetrics/api-report.md @@ -20,6 +20,7 @@ export const xcmetricsPlugin: BackstagePlugin< { root: RouteRef; }, + {}, {} >; ``` diff --git a/plugins/xcmetrics/package.json b/plugins/xcmetrics/package.json index 1527789e44..624c5c1f98 100644 --- a/plugins/xcmetrics/package.json +++ b/plugins/xcmetrics/package.json @@ -1,7 +1,7 @@ { "name": "@backstage/plugin-xcmetrics", "description": "A Backstage plugin that shows XCode build metrics for your components", - "version": "0.2.27-next.3", + "version": "0.2.28", "main": "src/index.ts", "types": "src/index.ts", "license": "Apache-2.0", @@ -24,10 +24,10 @@ "clean": "backstage-cli package clean" }, "dependencies": { - "@backstage/core-components": "^0.10.0-next.3", - "@backstage/core-plugin-api": "^1.0.4-next.0", - "@backstage/errors": "^1.1.0-next.0", - "@backstage/theme": "^0.2.16-next.1", + "@backstage/core-components": "^0.11.0", + "@backstage/core-plugin-api": "^1.0.5", + "@backstage/errors": "^1.1.0", + "@backstage/theme": "^0.2.16", "@material-ui/core": "^4.12.2", "@material-ui/icons": "^4.9.1", "@material-ui/lab": "4.0.0-alpha.57", @@ -40,18 +40,18 @@ "react": "^16.13.1 || ^17.0.0" }, "devDependencies": { - "@backstage/cli": "^0.18.0-next.3", - "@backstage/core-app-api": "^1.0.4-next.1", - "@backstage/dev-utils": "^1.0.4-next.3", - "@backstage/test-utils": "^1.1.2-next.2", + "@backstage/cli": "^0.18.1", + "@backstage/core-app-api": "^1.0.5", + "@backstage/dev-utils": "^1.0.5", + "@backstage/test-utils": "^1.1.3", "@testing-library/jest-dom": "^5.10.1", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^14.0.0", "@types/jest": "^26.0.7", - "@types/luxon": "^2.0.4", + "@types/luxon": "^3.0.0", "@types/node": "^16.11.26", "cross-fetch": "^3.1.5", - "msw": "^0.44.0" + "msw": "^0.45.0" }, "files": [ "dist" diff --git a/scripts/api-extractor.ts b/scripts/api-extractor.ts index 32b27e06ca..be1f9ce038 100644 --- a/scripts/api-extractor.ts +++ b/scripts/api-extractor.ts @@ -201,14 +201,8 @@ const ALLOW_WARNINGS = [ 'packages/core-components', 'plugins/allure', 'plugins/apache-airflow', - 'plugins/api-docs', 'plugins/app-backend', 'plugins/auth-backend', - 'plugins/azure-devops', - 'plugins/azure-devops-backend', - 'plugins/azure-devops-common', - 'plugins/badges', - 'plugins/badges-backend', 'plugins/bitrise', 'plugins/catalog', 'plugins/catalog-graphql', @@ -223,7 +217,6 @@ const ALLOW_WARNINGS = [ 'plugins/explore', 'plugins/explore-react', 'plugins/firehydrant', - 'plugins/fossa', 'plugins/gcalendar', 'plugins/gcp-projects', 'plugins/git-release-manager', @@ -236,21 +229,16 @@ const ALLOW_WARNINGS = [ 'plugins/ilert', 'plugins/jenkins', 'plugins/jenkins-backend', - 'plugins/kafka', - 'plugins/kafka-backend', 'plugins/kubernetes', 'plugins/kubernetes-common', - 'plugins/lighthouse', 'plugins/newrelic', 'plugins/newrelic-dashboard', 'plugins/pagerduty', - 'plugins/proxy-backend', 'plugins/rollbar', 'plugins/rollbar-backend', 'plugins/search-backend-module-pg', 'plugins/sentry', 'plugins/shortcuts', - 'plugins/sonarqube', 'plugins/splunk-on-call', 'plugins/tech-radar', 'plugins/user-settings', diff --git a/storybook/yarn.lock b/storybook/yarn.lock index 3863f311c4..364b87607b 100644 --- a/storybook/yarn.lock +++ b/storybook/yarn.lock @@ -10,17 +10,17 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" - integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== dependencies: - "@babel/highlight" "^7.16.7" + "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.17.10": - version "7.18.5" - resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.5.tgz#acac0c839e317038c73137fbb6ef71a1d6238471" - integrity sha512-BxhE40PVCBxVEJsSBhB6UWyAuqJRxGsAw8BdHMJ3AKGydcwuWW4kOO3HmqBQAdcq/OP+/DlTVxLvsCzRTnZuGg== +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8": + version "7.18.8" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== "@babel/core@7.12.9": version "7.12.9" @@ -45,80 +45,80 @@ source-map "^0.5.0" "@babel/core@^7.12.10", "@babel/core@^7.7.5": - version "7.18.5" - resolved "https://registry.npmjs.org/@babel/core/-/core-7.18.5.tgz#c597fa680e58d571c28dda9827669c78cdd7f000" - integrity sha512-MGY8vg3DxMnctw0LdvSEojOsumc70g0t18gNyUdAZqB1Rpd1Bqo/svHGvt+UJ6JcGX+DIekGFDxxIWofBxLCnQ== + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8" + integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw== dependencies: "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.18.2" - "@babel/helper-compilation-targets" "^7.18.2" - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helpers" "^7.18.2" - "@babel/parser" "^7.18.5" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.18.5" - "@babel/types" "^7.18.4" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.10" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.18.10" + "@babel/types" "^7.18.10" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.1" semver "^6.3.0" -"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.18.2": - version "7.18.2" - resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz#33873d6f89b21efe2da63fe554460f3df1c5880d" - integrity sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw== +"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.18.10": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.18.10.tgz#794f328bfabdcbaf0ebf9bf91b5b57b61fa77a2a" + integrity sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA== dependencies: - "@babel/types" "^7.18.2" - "@jridgewell/gen-mapping" "^0.3.0" + "@babel/types" "^7.18.10" + "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" - integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" - integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" + integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== dependencies: - "@babel/helper-explode-assignable-expression" "^7.16.7" - "@babel/types" "^7.16.7" + "@babel/helper-explode-assignable-expression" "^7.18.6" + "@babel/types" "^7.18.9" -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7", "@babel/helper-compilation-targets@^7.17.10", "@babel/helper-compilation-targets@^7.18.2": - version "7.18.2" - resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz#67a85a10cbd5fc7f1457fec2e7f45441dc6c754b" - integrity sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ== +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" + integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-validator-option" "^7.16.7" + "@babel/compat-data" "^7.18.8" + "@babel/helper-validator-option" "^7.18.6" browserslist "^4.20.2" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.17.12", "@babel/helper-create-class-features-plugin@^7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.0.tgz#fac430912606331cb075ea8d82f9a4c145a4da19" - integrity sha512-Kh8zTGR9de3J63e5nS0rQUdRs/kbtwoeQQ0sriS0lItjC96u8XXZN6lKpuyWd2coKSU13py/y+LTmThLuVX0Pg== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz#d802ee16a64a9e824fcbf0a2ffc92f19d58550ce" + integrity sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-member-expression-to-functions" "^7.17.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" -"@babel/helper-create-regexp-features-plugin@^7.16.7", "@babel/helper-create-regexp-features-plugin@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.12.tgz#bb37ca467f9694bbe55b884ae7a5cc1e0084e4fd" - integrity sha512-b2aZrV4zvutr9AIa6/gA3wsZKRwTKYoDxYiFKcESS3Ug2GTXzwBEvMuuFLhCQpEnRXs1zng4ISAXSUxxKBIcxw== +"@babel/helper-create-regexp-features-plugin@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz#3e35f4e04acbbf25f1b3534a657610a000543d3c" + integrity sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - regexpu-core "^5.0.1" + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.1.0" "@babel/helper-define-polyfill-provider@^0.1.5": version "0.1.5" @@ -134,284 +134,288 @@ resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-define-polyfill-provider@^0.3.1": - version "0.3.1" - resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" - integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== +"@babel/helper-define-polyfill-provider@^0.3.2": + version "0.3.2" + resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz#bd10d0aca18e8ce012755395b05a79f45eca5073" + integrity sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg== dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" debug "^4.1.1" lodash.debounce "^4.0.8" resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-environment-visitor@^7.16.7", "@babel/helper-environment-visitor@^7.18.2": - version "7.18.2" - resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz#8a6d2dedb53f6bf248e31b4baf38739ee4a637bd" - integrity sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ== +"@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== -"@babel/helper-explode-assignable-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" - integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== +"@babel/helper-explode-assignable-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" + integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" -"@babel/helper-function-name@^7.16.7", "@babel/helper-function-name@^7.17.9": - version "7.17.9" - resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" - integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== +"@babel/helper-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" + integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== dependencies: - "@babel/template" "^7.16.7" - "@babel/types" "^7.17.0" + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.9" -"@babel/helper-hoist-variables@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" - integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" -"@babel/helper-member-expression-to-functions@^7.17.7": - version "7.17.7" - resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4" - integrity sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw== +"@babel/helper-member-expression-to-functions@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" + integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== dependencies: - "@babel/types" "^7.17.0" + "@babel/types" "^7.18.9" -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" - integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" -"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz#baf05dec7a5875fb9235bd34ca18bad4e21221cd" - integrity sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA== +"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" + integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== dependencies: - "@babel/helper-environment-visitor" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-simple-access" "^7.17.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.18.0" - "@babel/types" "^7.18.0" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" -"@babel/helper-optimise-call-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" - integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== +"@babel/helper-optimise-call-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" + integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" "@babel/helper-plugin-utils@7.10.4": version "7.10.4" resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.17.12", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96" - integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f" + integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w== -"@babel/helper-remap-async-to-generator@^7.16.8": - version "7.16.8" - resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" - integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== +"@babel/helper-remap-async-to-generator@^7.18.6", "@babel/helper-remap-async-to-generator@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" + integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-wrap-function" "^7.16.8" - "@babel/types" "^7.16.8" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-wrap-function" "^7.18.9" + "@babel/types" "^7.18.9" -"@babel/helper-replace-supers@^7.16.7", "@babel/helper-replace-supers@^7.18.2": - version "7.18.2" - resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.2.tgz#41fdfcc9abaf900e18ba6e5931816d9062a7b2e0" - integrity sha512-XzAIyxx+vFnrOxiQrToSUOzUOn0e1J2Li40ntddek1Y69AXUTXoDJ40/D5RdjFu7s7qHiaeoTiempZcbuVXh2Q== +"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6" + integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ== dependencies: - "@babel/helper-environment-visitor" "^7.18.2" - "@babel/helper-member-expression-to-functions" "^7.17.7" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/traverse" "^7.18.2" - "@babel/types" "^7.18.2" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" -"@babel/helper-simple-access@^7.17.7", "@babel/helper-simple-access@^7.18.2": - version "7.18.2" - resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz#4dc473c2169ac3a1c9f4a51cfcd091d1c36fcff9" - integrity sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ== +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== dependencies: - "@babel/types" "^7.18.2" + "@babel/types" "^7.18.6" -"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": - version "7.16.0" - resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" - integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== +"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" + integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== dependencies: - "@babel/types" "^7.16.0" + "@babel/types" "^7.18.9" -"@babel/helper-split-export-declaration@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" - integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" -"@babel/helper-validator-identifier@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" - integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== +"@babel/helper-string-parser@^7.18.10": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz#181f22d28ebe1b3857fa575f5c290b1aaf659b56" + integrity sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw== -"@babel/helper-validator-option@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" - integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== -"@babel/helper-wrap-function@^7.16.8": - version "7.16.8" - resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" - integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helper-wrap-function@^7.18.9": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.10.tgz#a7fcd3ab9b1be4c9b52cf7d7fdc1e88c2ce93396" + integrity sha512-95NLBP59VWdfK2lyLKe6eTMq9xg+yWKzxzxbJ1wcYNi1Auz200+83fMDADjRxBvc2QQor5zja2yTQzXGhk2GtQ== dependencies: - "@babel/helper-function-name" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.8" - "@babel/types" "^7.16.8" + "@babel/helper-function-name" "^7.18.9" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.18.10" + "@babel/types" "^7.18.10" -"@babel/helpers@^7.12.5", "@babel/helpers@^7.18.2": - version "7.18.2" - resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.2.tgz#970d74f0deadc3f5a938bfa250738eb4ac889384" - integrity sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg== +"@babel/helpers@^7.12.5", "@babel/helpers@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" + integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== dependencies: - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.18.2" - "@babel/types" "^7.18.2" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" -"@babel/highlight@^7.16.7": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz#257de56ee5afbd20451ac0a75686b6b404257351" - integrity sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg== +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== dependencies: - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-validator-identifier" "^7.18.6" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.16.7", "@babel/parser@^7.18.5": - version "7.18.5" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz#337062363436a893a2d22faa60be5bb37091c83c" - integrity sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw== +"@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.18.10": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.18.10.tgz#94b5f8522356e69e8277276adf67ed280c90ecc1" + integrity sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg== -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.17.12.tgz#1dca338caaefca368639c9ffb095afbd4d420b1e" - integrity sha512-xCJQXl4EeQ3J9C4yOmpTrtVGmzpm2iSzyxbkZHw7UCnZBftHpF/hpII80uWVyVrc40ytIClHjgWGTG1g/yB+aw== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" + integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.17.12.tgz#0d498ec8f0374b1e2eb54b9cb2c4c78714c77753" - integrity sha512-/vt0hpIw0x4b6BLKUkwlvEoiGZYYLNZ96CzyHYPbtG2jZGz6LBe7/V+drYrc/d+ovrF9NBi0pmtvmNb/FsWtRQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" + integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - "@babel/plugin-proposal-optional-chaining" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" -"@babel/plugin-proposal-async-generator-functions@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.17.12.tgz#094a417e31ce7e692d84bab06c8e2a607cbeef03" - integrity sha512-RWVvqD1ooLKP6IqWTA5GyFVX2isGEgC5iFxKzfYOIy/QEFdxYyCybBDtIGjipHpb9bDWHzcqGqFakf+mVmBTdQ== +"@babel/plugin-proposal-async-generator-functions@^7.18.10": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.10.tgz#85ea478c98b0095c3e4102bff3b67d306ed24952" + integrity sha512-1mFuY2TOsR1hxbjCo4QL+qlIjV07p4H4EUYw2J/WCqsvFV6V9X9z9YhXbWndc/4fw+hYGlDT7egYxliMp5O6Ew== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-remap-async-to-generator" "^7.18.9" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.17.12.tgz#84f65c0cc247d46f40a6da99aadd6438315d80a4" - integrity sha512-U0mI9q8pW5Q9EaTHFPwSVusPMV/DV9Mm8p7csqROFLtIE9rBF5piLqyrBGigftALrBcsBGu4m38JneAe7ZDLXw== +"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.17.12" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-class-static-block@^7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.0.tgz#7d02253156e3c3793bdb9f2faac3a1c05f0ba710" - integrity sha512-t+8LsRMMDE74c6sV7KShIw13sqbqd58tlqNrsWoWBTIMw7SVQ0cZ905wLNS/FBCy/3PyooRHLFFlfrUNyyz5lA== +"@babel/plugin-proposal-class-static-block@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" + integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-proposal-decorators@^7.12.12": - version "7.18.2" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.18.2.tgz#dbe4086d2d42db489399783c3aa9272e9700afd4" - integrity sha512-kbDISufFOxeczi0v4NQP3p5kIeW6izn/6klfWBrIIdGZZe4UpHR+QU03FAoWjGGd9SUXAwbw2pup1kaL4OQsJQ== + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.18.10.tgz#788650d01e518a8a722eb8b3055dd9d73ecb7a35" + integrity sha512-wdGTwWF5QtpTY/gbBtQLAiCnoxfD4qMbN87NYZle1dOZ9Os8Y6zXcKrIaOU8W+TIvFUWVGG9tUgNww3CjXRVVw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-replace-supers" "^7.18.2" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/plugin-syntax-decorators" "^7.17.12" - charcodes "^0.2.0" + "@babel/helper-create-class-features-plugin" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/plugin-syntax-decorators" "^7.18.6" -"@babel/plugin-proposal-dynamic-import@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" - integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== +"@babel/plugin-proposal-dynamic-import@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" + integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-proposal-export-default-from@^7.12.1": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.17.12.tgz#df785e638618d8ffa14e08c78c44d9695d083b73" - integrity sha512-LpsTRw725eBAXXKUOnJJct+SEaOzwR78zahcLuripD2+dKc2Sj+8Q2DzA+GC/jOpOu/KlDXuxrzG214o1zTauQ== + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.18.10.tgz#091f4794dbce4027c03cf4ebc64d3fb96b75c206" + integrity sha512-5H2N3R2aQFxkV4PIBUR/i7PUSwgTZjouJKzI8eKswfIjT0PhvzkPn0t0wIS5zn6maQuvtT0t1oHtMUz61LOuow== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/plugin-syntax-export-default-from" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-export-default-from" "^7.18.6" -"@babel/plugin-proposal-export-namespace-from@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.17.12.tgz#b22864ccd662db9606edb2287ea5fd1709f05378" - integrity sha512-j7Ye5EWdwoXOpRmo5QmRyHPsDIe6+u70ZYZrd7uz+ebPYFKfRcLcNu3Ro0vOlJ5zuv8rU7xa+GttNiRzX56snQ== +"@babel/plugin-proposal-export-namespace-from@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" + integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.17.12.tgz#f4642951792437233216d8c1af370bb0fbff4664" - integrity sha512-rKJ+rKBoXwLnIn7n6o6fulViHMrOThz99ybH+hKHcOZbnN14VuMnH9fo2eHE69C8pO4uX1Q7t2HYYIDmv8VYkg== +"@babel/plugin-proposal-json-strings@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" + integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.17.12.tgz#c64a1bcb2b0a6d0ed2ff674fd120f90ee4b88a23" - integrity sha512-EqFo2s1Z5yy+JeJu7SFfbIUtToJTVlC61/C7WLKDntSw4Sz6JNAIfL7zQ74VvirxpjB5kz/kIx0gCcb+5OEo2Q== +"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" + integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.17.12.tgz#1e93079bbc2cbc756f6db6a1925157c4a92b94be" - integrity sha512-ws/g3FSGVzv+VH86+QvgtuJL/kR67xaEIF2x0iPqdDfYW6ra6JF3lKVBkWynRLcNtIC1oCTfDRVxmm2mKzy+ag== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" - integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== +"@babel/plugin-proposal-numeric-separator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" + integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-proposal-object-rest-spread@7.12.1": @@ -423,59 +427,59 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-transform-parameters" "^7.12.1" -"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.0.tgz#79f2390c892ba2a68ec112eb0d895cfbd11155e8" - integrity sha512-nbTv371eTrFabDfHLElkn9oyf9VG+VKK6WMzhY2o4eHKaG19BToD9947zzGMO6I/Irstx9d8CwX6njPNIAR/yw== +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" + integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-compilation-targets" "^7.17.10" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/compat-data" "^7.18.8" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.17.12" + "@babel/plugin-transform-parameters" "^7.18.8" -"@babel/plugin-proposal-optional-catch-binding@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" - integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== +"@babel/plugin-proposal-optional-catch-binding@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" + integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.17.12.tgz#f96949e9bacace3a9066323a5cf90cfb9de67174" - integrity sha512-7wigcOs/Z4YWlK7xxjkvaIw84vGhDv/P1dFGQap0nHkc8gFKY/r+hXc8Qzf5k1gY7CvGIcHqAnOagVKJJ1wVOQ== +"@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" + integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.12.1", "@babel/plugin-proposal-private-methods@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.17.12.tgz#c2ca3a80beb7539289938da005ad525a038a819c" - integrity sha512-SllXoxo19HmxhDWm3luPz+cPhtoTSKLJE9PXshsfrOzBqs60QP0r8OaJItrPhAj0d7mZMnNF0Y1UUggCDgMz1A== +"@babel/plugin-proposal-private-methods@^7.12.1", "@babel/plugin-proposal-private-methods@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" + integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.17.12" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-private-property-in-object@^7.12.1", "@babel/plugin-proposal-private-property-in-object@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.17.12.tgz#b02efb7f106d544667d91ae97405a9fd8c93952d" - integrity sha512-/6BtVi57CJfrtDNKfK5b66ydK2J5pXUKBKSPD2G1whamMuEnZWgoOIfO8Vf9F/DoD4izBLD/Au4NMQfruzzykg== +"@babel/plugin-proposal-private-property-in-object@^7.12.1", "@babel/plugin-proposal-private-property-in-object@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503" + integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-create-class-features-plugin" "^7.17.12" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.17.12", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.17.12.tgz#3dbd7a67bd7f94c8238b394da112d86aaf32ad4d" - integrity sha512-Wb9qLjXf3ZazqXA7IvI7ozqRIXIGPtSo+L5coFmEkhTQK18ao4UDDD0zdTGAarmbLj2urpRwrc6893cu5Bfh0A== +"@babel/plugin-proposal-unicode-property-regex@^7.18.6", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" + integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.17.12" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -498,12 +502,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-decorators@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.17.12.tgz#02e8f678602f0af8222235271efea945cfdb018a" - integrity sha512-D1Hz0qtGTza8K2xGyEdVNCYLdVHukAcbQr4K3/s6r/esadyEriZovpJimQOpu8ju4/jV8dW/1xdaE0UpDroidw== +"@babel/plugin-syntax-decorators@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.18.6.tgz#2e45af22835d0b0f8665da2bfd4463649ce5dbc1" + integrity sha512-fqyLgjcxf/1yhyZ6A+yo1u9gJ7eleFQod2lkaUsF9DQ7sbbY3Ligym3L0+I2c0WmqNKDpoD9UTb1AKP3qRMOAQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" @@ -512,12 +516,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-export-default-from@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.16.7.tgz#fa89cf13b60de2c3f79acdc2b52a21174c6de060" - integrity sha512-4C3E4NsrLOgftKaTYTULhHsuQrGv3FHrBzOMDiS7UYKIpgGBkAdawg4h+EI8zPeK9M0fiIIh72hIwsI24K7MbA== +"@babel/plugin-syntax-export-default-from@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.18.6.tgz#8df076711a4818c4ce4f23e61d622b0ba2ff84bc" + integrity sha512-Kr//z3ujSVNx6E9z9ih5xXXMqK07VVTuqPmqGe6Mss/zW5XPeLZeSDZoP9ab/hT4wPKqAgjl2PnhPrcpk8Seew== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-export-namespace-from@^7.8.3": version "7.8.3" @@ -526,19 +530,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-flow@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.17.12.tgz#23d852902acd19f42923fca9d0f196984d124e73" - integrity sha512-B8QIgBvkIG6G2jgsOHQUist7Sm0EBLDCx8sen072IwqNuzMegZNXrYnSv77cYzA8mLDZAfQYqsLIhimiP1s2HQ== +"@babel/plugin-syntax-flow@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz#774d825256f2379d06139be0c723c4dd444f3ca1" + integrity sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-syntax-import-assertions@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.17.12.tgz#58096a92b11b2e4e54b24c6a0cc0e5e607abcedd" - integrity sha512-n/loy2zkq9ZEM8tEOwON9wTQSTNDTDEz6NujPtJGLU7qObzT1N4c4YZZf8E6ATB2AjNQg/Ib2AIpO03EZaCehw== +"@babel/plugin-syntax-import-assertions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4" + integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" @@ -554,12 +558,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-jsx@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.17.12.tgz#834035b45061983a491f60096f61a2e7c5674a47" - integrity sha512-spyY3E3AURfxh/RHtjx5j6hs8am5NbUBGfcZ2vB3uShSpZdQyXSf5rR5Mk76vbtlAZOelyVQ71Fg0x9SG4fsog== +"@babel/plugin-syntax-jsx@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" @@ -617,347 +621,347 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz#b54fc3be6de734a56b87508f99d6428b5b605a7b" - integrity sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw== +"@babel/plugin-syntax-typescript@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" + integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.17.12.tgz#dddd783b473b1b1537ef46423e3944ff24898c45" - integrity sha512-PHln3CNi/49V+mza4xMwrg+WGYevSF1oaiXaC2EQfdp4HWlSjRsrDXWJiQBKpP7749u6vQ9mcry2uuFOv5CXvA== +"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" + integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-async-to-generator@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.17.12.tgz#dbe5511e6b01eee1496c944e35cdfe3f58050832" - integrity sha512-J8dbrWIOO3orDzir57NRsjg4uxucvhby0L/KZuGsWDj0g7twWK3g7JhJhOrXtuXiw8MeiSdJ3E0OW9H8LYEzLQ== +"@babel/plugin-transform-async-to-generator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" + integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" -"@babel/plugin-transform-block-scoped-functions@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" - integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== +"@babel/plugin-transform-block-scoped-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" + integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.17.12": - version "7.18.4" - resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.4.tgz#7988627b3e9186a13e4d7735dc9c34a056613fb9" - integrity sha512-+Hq10ye+jlvLEogSOtq4mKvtk7qwcUQ1f0Mrueai866C82f844Yom2cttfJdMdqRLTxWpsbfbkIkOIfovyUQXw== +"@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" + integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.17.12": - version "7.18.4" - resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.4.tgz#51310b812a090b846c784e47087fa6457baef814" - integrity sha512-e42NSG2mlKWgxKUAD9EJJSkZxR67+wZqzNxLSpc51T8tRU5SLFHsPmgYR5yr7sdgX4u+iHA1C5VafJ6AyImV3A== +"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz#90818efc5b9746879b869d5ce83eb2aa48bbc3da" + integrity sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-environment-visitor" "^7.18.2" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-optimise-call-expression" "^7.16.7" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-replace-supers" "^7.18.2" - "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.17.12.tgz#bca616a83679698f3258e892ed422546e531387f" - integrity sha512-a7XINeplB5cQUWMg1E/GI1tFz3LfK021IjV1rj1ypE+R7jHm+pIHmHl25VNkZxtx9uuYp7ThGk8fur1HHG7PgQ== +"@babel/plugin-transform-computed-properties@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" + integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.0.tgz#dc4f92587e291b4daa78aa20cc2d7a63aa11e858" - integrity sha512-Mo69klS79z6KEfrLg/1WkmVnB8javh75HX4pi2btjvlIoasuxilEyjtsQW6XPrubNd7AQy0MMaNIaQE4e7+PQw== +"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.9.tgz#68906549c021cb231bee1db21d3b5b095f8ee292" + integrity sha512-p5VCYNddPLkZTq4XymQIaIfZNJwT9YsjkPOhkVEqt6QIpQFZVM9IltqqYpOEkJoN1DPznmxUDyZ5CTZs/ZCuHA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-dotall-regex@^7.16.7", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" - integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== +"@babel/plugin-transform-dotall-regex@^7.18.6", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" + integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-duplicate-keys@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.17.12.tgz#a09aa709a3310013f8e48e0e23bc7ace0f21477c" - integrity sha512-EA5eYFUG6xeerdabina/xIoB95jJ17mAkR8ivx6ZSu9frKShBjpOGZPn511MTDTkiCO+zXnzNczvUM69YSf3Zw== +"@babel/plugin-transform-duplicate-keys@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" + integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-exponentiation-operator@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" - integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== +"@babel/plugin-transform-exponentiation-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" + integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-flow-strip-types@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.17.12.tgz#5e070f99a4152194bd9275de140e83a92966cab3" - integrity sha512-g8cSNt+cHCpG/uunPQELdq/TeV3eg1OLJYwxypwHtAWo9+nErH3lQx9CSO2uI9lF74A0mR0t4KoMjs1snSgnTw== +"@babel/plugin-transform-flow-strip-types@^7.18.6": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.18.9.tgz#5b4cc521426263b5ce08893a2db41097ceba35bf" + integrity sha512-+G6rp2zRuOAInY5wcggsx4+QVao1qPM0osC9fTUVlAV3zOrzTCnrMAFVnR6+a3T8wz1wFIH7KhYMcMB3u1n80A== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/plugin-syntax-flow" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-flow" "^7.18.6" -"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.18.1": - version "7.18.1" - resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.1.tgz#ed14b657e162b72afbbb2b4cdad277bf2bb32036" - integrity sha512-+TTB5XwvJ5hZbO8xvl2H4XaMDOAK57zF4miuC9qQJgysPNEAZZ9Z69rdF5LJkozGdZrjBIUAIyKUWRMmebI7vg== +"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.18.8": + version "7.18.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" + integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-function-name@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" - integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== +"@babel/plugin-transform-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" + integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== dependencies: - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-function-name" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-literals@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.17.12.tgz#97131fbc6bbb261487105b4b3edbf9ebf9c830ae" - integrity sha512-8iRkvaTjJciWycPIZ9k9duu663FT7VrBdNqNgxnVXEFwOIp55JWcZd23VBRySYbnS3PwQ3rGiabJBBBGj5APmQ== +"@babel/plugin-transform-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" + integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-member-expression-literals@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" - integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== +"@babel/plugin-transform-member-expression-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" + integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-modules-amd@^7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.0.tgz#7ef1002e67e36da3155edc8bf1ac9398064c02ed" - integrity sha512-h8FjOlYmdZwl7Xm2Ug4iX2j7Qy63NANI+NQVWQzv6r25fqgg7k2dZl03p95kvqNclglHs4FZ+isv4p1uXMA+QA== +"@babel/plugin-transform-modules-amd@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21" + integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== dependencies: - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.18.2": - version "7.18.2" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.2.tgz#1aa8efa2e2a6e818b6a7f2235fceaf09bdb31e9e" - integrity sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ== +"@babel/plugin-transform-modules-commonjs@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" + integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== dependencies: - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-simple-access" "^7.18.2" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.18.0": - version "7.18.5" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.5.tgz#87f11c44fbfd3657be000d4897e192d9cb535996" - integrity sha512-SEewrhPpcqMF1V7DhnEbhVJLrC+nnYfe1E0piZMZXBpxi9WvZqWGwpsk7JYP7wPWeqaBh4gyKlBhHJu3uz5g4Q== +"@babel/plugin-transform-modules-systemjs@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz#545df284a7ac6a05125e3e405e536c5853099a06" + integrity sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A== dependencies: - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-validator-identifier" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.0.tgz#56aac64a2c2a1922341129a4597d1fd5c3ff020f" - integrity sha512-d/zZ8I3BWli1tmROLxXLc9A6YXvGK8egMxHp+E/rRwMh1Kip0AP77VwZae3snEJ33iiWwvNv2+UIIhfalqhzZA== +"@babel/plugin-transform-modules-umd@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" + integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== dependencies: - "@babel/helper-module-transforms" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-named-capturing-groups-regex@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.17.12.tgz#9c4a5a5966e0434d515f2675c227fd8cc8606931" - integrity sha512-vWoWFM5CKaTeHrdUJ/3SIOTRV+MBVGybOC9mhJkaprGNt5demMymDW24yC74avb915/mIRe3TgNb/d8idvnCRA== +"@babel/plugin-transform-named-capturing-groups-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz#c89bfbc7cc6805d692f3a49bc5fc1b630007246d" + integrity sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.17.12" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-new-target@^7.17.12": - version "7.18.5" - resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.5.tgz#8c228c4a07501dd12c95c5f23d1622131cc23931" - integrity sha512-TuRL5uGW4KXU6OsRj+mLp9BM7pO8e7SGNTEokQRRxHFkXYMFiy2jlKSZPFtI/mKORDzciH+hneskcSOp0gU8hg== +"@babel/plugin-transform-new-target@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" + integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-object-super@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" - integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== +"@babel/plugin-transform-object-super@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" + integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" -"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.17.12.tgz#eb467cd9586ff5ff115a9880d6fdbd4a846b7766" - integrity sha512-6qW4rWo1cyCdq1FkYri7AHpauchbGLXpdwnYsfxFb+KtddHENfsY5JZb35xUwkK5opOLcJ3BNd2l7PhRYGlwIA== +"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.18.8": + version "7.18.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" + integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-property-literals@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" - integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== +"@babel/plugin-transform-property-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" + integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-react-display-name@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz#7b6d40d232f4c0f550ea348593db3b21e2404340" - integrity sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg== +"@babel/plugin-transform-react-display-name@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" + integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-react-jsx-development@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz#43a00724a3ed2557ed3f276a01a929e6686ac7b8" - integrity sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A== +"@babel/plugin-transform-react-jsx-development@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" + integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== dependencies: - "@babel/plugin-transform-react-jsx" "^7.16.7" + "@babel/plugin-transform-react-jsx" "^7.18.6" -"@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.16.7", "@babel/plugin-transform-react-jsx@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz#2aa20022709cd6a3f40b45d60603d5f269586dba" - integrity sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ== +"@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.18.6": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.18.10.tgz#ea47b2c4197102c196cbd10db9b3bb20daa820f1" + integrity sha512-gCy7Iikrpu3IZjYZolFE4M1Sm+nrh1/6za2Ewj77Z+XirT4TsbJcvOFOyF+fRPwU6AKKK136CZxx6L8AbSFG6A== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/plugin-syntax-jsx" "^7.17.12" - "@babel/types" "^7.17.12" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-jsx" "^7.18.6" + "@babel/types" "^7.18.10" -"@babel/plugin-transform-react-pure-annotations@^7.16.7": - version "7.18.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.0.tgz#ef82c8e310913f3522462c9ac967d395092f1954" - integrity sha512-6+0IK6ouvqDn9bmEG7mEyF/pwlJXVj5lwydybpyyH3D0A7Hftk+NCTdYjnLNZksn261xaOV5ksmp20pQEmc2RQ== +"@babel/plugin-transform-react-pure-annotations@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz#561af267f19f3e5d59291f9950fd7b9663d0d844" + integrity sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-regenerator@^7.18.0": - version "7.18.0" - resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.0.tgz#44274d655eb3f1af3f3a574ba819d3f48caf99d5" - integrity sha512-C8YdRw9uzx25HSIzwA7EM7YP0FhCe5wNvJbZzjVNHHPGVcDJ3Aie+qGYYdS1oVQgn+B3eAIJbWFLrJ4Jipv7nw== +"@babel/plugin-transform-regenerator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73" + integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" regenerator-transform "^0.15.0" -"@babel/plugin-transform-reserved-words@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.17.12.tgz#7dbd349f3cdffba751e817cf40ca1386732f652f" - integrity sha512-1KYqwbJV3Co03NIi14uEHW8P50Md6KqFgt0FfpHdK6oyAHQVTosgPuPSiWud1HX0oYJ1hGRRlk0fP87jFpqXZA== +"@babel/plugin-transform-reserved-words@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" + integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" - integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== +"@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" + integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.17.12.tgz#c112cad3064299f03ea32afed1d659223935d1f5" - integrity sha512-9pgmuQAtFi3lpNUstvG9nGfk9DkrdmWNp9KeKPFmuZCpEnxRzYlS8JgwPjYj+1AWDOSvoGN0H30p1cBOmT/Svg== +"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz#6ea7a6297740f381c540ac56caf75b05b74fb664" + integrity sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" -"@babel/plugin-transform-sticky-regex@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" - integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== +"@babel/plugin-transform-sticky-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" + integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.18.2": - version "7.18.2" - resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.2.tgz#31ed6915721864847c48b656281d0098ea1add28" - integrity sha512-/cmuBVw9sZBGZVOMkpAEaVLwm4JmK2GZ1dFKOGGpMzEHWFmyZZ59lUU0PdRr8YNYeQdNzTDwuxP2X2gzydTc9g== +"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" + integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-typeof-symbol@^7.17.12": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.17.12.tgz#0f12f57ac35e98b35b4ed34829948d42bd0e6889" - integrity sha512-Q8y+Jp7ZdtSPXCThB6zjQ74N3lj0f6TDh1Hnf5B+sYlzQ8i5Pjp8gW0My79iekSpT4WnI06blqP6DT0OmaXXmw== +"@babel/plugin-transform-typeof-symbol@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" + integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-typescript@^7.17.12": - version "7.18.4" - resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.4.tgz#587eaf6a39edb8c06215e550dc939faeadd750bf" - integrity sha512-l4vHuSLUajptpHNEOUDEGsnpl9pfRLsN1XUoDQDD/YBuXTM+v37SHGS+c6n4jdcZy96QtuUuSvZYMLSSsjH8Mw== +"@babel/plugin-transform-typescript@^7.18.6": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.10.tgz#b23401b32f1f079396bcaed01667a54ebe4f9f85" + integrity sha512-j2HQCJuMbi88QftIb5zlRu3c7PU+sXNnscqsrjqegoGiCgXR569pEdben9vly5QHKL2ilYkfnSwu64zsZo/VYQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.0" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/plugin-syntax-typescript" "^7.17.12" + "@babel/helper-create-class-features-plugin" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-typescript" "^7.18.6" -"@babel/plugin-transform-unicode-escapes@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" - integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q== +"@babel/plugin-transform-unicode-escapes@^7.18.10": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz#1ecfb0eda83d09bbcb77c09970c2dd55832aa246" + integrity sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-unicode-regex@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" - integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== +"@babel/plugin-transform-unicode-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" + integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/preset-env@^7.12.11": - version "7.18.2" - resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.2.tgz#f47d3000a098617926e674c945d95a28cb90977a" - integrity sha512-PfpdxotV6afmXMU47S08F9ZKIm2bJIQ0YbAAtDfIENX7G1NUAXigLREh69CWDjtgUy7dYn7bsMzkgdtAlmS68Q== + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.10.tgz#83b8dfe70d7eea1aae5a10635ab0a5fe60dfc0f4" + integrity sha512-wVxs1yjFdW3Z/XkNfXKoblxoHgbtUF7/l3PvvP4m02Qz9TZ6uZGxRVYjSQeR87oQmHco9zWitW5J82DJ7sCjvA== dependencies: - "@babel/compat-data" "^7.17.10" - "@babel/helper-compilation-targets" "^7.18.2" - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.17.12" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.17.12" - "@babel/plugin-proposal-async-generator-functions" "^7.17.12" - "@babel/plugin-proposal-class-properties" "^7.17.12" - "@babel/plugin-proposal-class-static-block" "^7.18.0" - "@babel/plugin-proposal-dynamic-import" "^7.16.7" - "@babel/plugin-proposal-export-namespace-from" "^7.17.12" - "@babel/plugin-proposal-json-strings" "^7.17.12" - "@babel/plugin-proposal-logical-assignment-operators" "^7.17.12" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.17.12" - "@babel/plugin-proposal-numeric-separator" "^7.16.7" - "@babel/plugin-proposal-object-rest-spread" "^7.18.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.16.7" - "@babel/plugin-proposal-optional-chaining" "^7.17.12" - "@babel/plugin-proposal-private-methods" "^7.17.12" - "@babel/plugin-proposal-private-property-in-object" "^7.17.12" - "@babel/plugin-proposal-unicode-property-regex" "^7.17.12" + "@babel/compat-data" "^7.18.8" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-async-generator-functions" "^7.18.10" + "@babel/plugin-proposal-class-properties" "^7.18.6" + "@babel/plugin-proposal-class-static-block" "^7.18.6" + "@babel/plugin-proposal-dynamic-import" "^7.18.6" + "@babel/plugin-proposal-export-namespace-from" "^7.18.9" + "@babel/plugin-proposal-json-strings" "^7.18.6" + "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" + "@babel/plugin-proposal-numeric-separator" "^7.18.6" + "@babel/plugin-proposal-object-rest-spread" "^7.18.9" + "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-private-methods" "^7.18.6" + "@babel/plugin-proposal-private-property-in-object" "^7.18.6" + "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.17.12" + "@babel/plugin-syntax-import-assertions" "^7.18.6" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -967,54 +971,54 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.17.12" - "@babel/plugin-transform-async-to-generator" "^7.17.12" - "@babel/plugin-transform-block-scoped-functions" "^7.16.7" - "@babel/plugin-transform-block-scoping" "^7.17.12" - "@babel/plugin-transform-classes" "^7.17.12" - "@babel/plugin-transform-computed-properties" "^7.17.12" - "@babel/plugin-transform-destructuring" "^7.18.0" - "@babel/plugin-transform-dotall-regex" "^7.16.7" - "@babel/plugin-transform-duplicate-keys" "^7.17.12" - "@babel/plugin-transform-exponentiation-operator" "^7.16.7" - "@babel/plugin-transform-for-of" "^7.18.1" - "@babel/plugin-transform-function-name" "^7.16.7" - "@babel/plugin-transform-literals" "^7.17.12" - "@babel/plugin-transform-member-expression-literals" "^7.16.7" - "@babel/plugin-transform-modules-amd" "^7.18.0" - "@babel/plugin-transform-modules-commonjs" "^7.18.2" - "@babel/plugin-transform-modules-systemjs" "^7.18.0" - "@babel/plugin-transform-modules-umd" "^7.18.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.17.12" - "@babel/plugin-transform-new-target" "^7.17.12" - "@babel/plugin-transform-object-super" "^7.16.7" - "@babel/plugin-transform-parameters" "^7.17.12" - "@babel/plugin-transform-property-literals" "^7.16.7" - "@babel/plugin-transform-regenerator" "^7.18.0" - "@babel/plugin-transform-reserved-words" "^7.17.12" - "@babel/plugin-transform-shorthand-properties" "^7.16.7" - "@babel/plugin-transform-spread" "^7.17.12" - "@babel/plugin-transform-sticky-regex" "^7.16.7" - "@babel/plugin-transform-template-literals" "^7.18.2" - "@babel/plugin-transform-typeof-symbol" "^7.17.12" - "@babel/plugin-transform-unicode-escapes" "^7.16.7" - "@babel/plugin-transform-unicode-regex" "^7.16.7" + "@babel/plugin-transform-arrow-functions" "^7.18.6" + "@babel/plugin-transform-async-to-generator" "^7.18.6" + "@babel/plugin-transform-block-scoped-functions" "^7.18.6" + "@babel/plugin-transform-block-scoping" "^7.18.9" + "@babel/plugin-transform-classes" "^7.18.9" + "@babel/plugin-transform-computed-properties" "^7.18.9" + "@babel/plugin-transform-destructuring" "^7.18.9" + "@babel/plugin-transform-dotall-regex" "^7.18.6" + "@babel/plugin-transform-duplicate-keys" "^7.18.9" + "@babel/plugin-transform-exponentiation-operator" "^7.18.6" + "@babel/plugin-transform-for-of" "^7.18.8" + "@babel/plugin-transform-function-name" "^7.18.9" + "@babel/plugin-transform-literals" "^7.18.9" + "@babel/plugin-transform-member-expression-literals" "^7.18.6" + "@babel/plugin-transform-modules-amd" "^7.18.6" + "@babel/plugin-transform-modules-commonjs" "^7.18.6" + "@babel/plugin-transform-modules-systemjs" "^7.18.9" + "@babel/plugin-transform-modules-umd" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.18.6" + "@babel/plugin-transform-new-target" "^7.18.6" + "@babel/plugin-transform-object-super" "^7.18.6" + "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-property-literals" "^7.18.6" + "@babel/plugin-transform-regenerator" "^7.18.6" + "@babel/plugin-transform-reserved-words" "^7.18.6" + "@babel/plugin-transform-shorthand-properties" "^7.18.6" + "@babel/plugin-transform-spread" "^7.18.9" + "@babel/plugin-transform-sticky-regex" "^7.18.6" + "@babel/plugin-transform-template-literals" "^7.18.9" + "@babel/plugin-transform-typeof-symbol" "^7.18.9" + "@babel/plugin-transform-unicode-escapes" "^7.18.10" + "@babel/plugin-transform-unicode-regex" "^7.18.6" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.18.2" - babel-plugin-polyfill-corejs2 "^0.3.0" - babel-plugin-polyfill-corejs3 "^0.5.0" - babel-plugin-polyfill-regenerator "^0.3.0" + "@babel/types" "^7.18.10" + babel-plugin-polyfill-corejs2 "^0.3.2" + babel-plugin-polyfill-corejs3 "^0.5.3" + babel-plugin-polyfill-regenerator "^0.4.0" core-js-compat "^3.22.1" semver "^6.3.0" "@babel/preset-flow@^7.12.1": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.17.12.tgz#664a5df59190260939eee862800a255bef3bd66f" - integrity sha512-7QDz7k4uiaBdu7N89VKjUn807pJRXmdirQu0KyR9LXnQrr5Jt41eIMKTS7ljej+H29erwmMrwq9Io9mJHLI3Lw== + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/preset-flow/-/preset-flow-7.18.6.tgz#83f7602ba566e72a9918beefafef8ef16d2810cb" + integrity sha512-E7BDhL64W6OUqpuyHnSroLnqyRTcG6ZdOBl1OKI/QK/HJfplqK/S3sq1Cckx7oTodJ5yOXyfw7rEADJ6UjoQDQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-transform-flow-strip-types" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-flow-strip-types" "^7.18.6" "@babel/preset-modules@^0.1.5": version "0.1.5" @@ -1028,30 +1032,30 @@ esutils "^2.0.2" "@babel/preset-react@^7.12.10": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.17.12.tgz#62adbd2d1870c0de3893095757ed5b00b492ab3d" - integrity sha512-h5U+rwreXtZaRBEQhW1hOJLMq8XNJBQ/9oymXiCXTuT/0uOwpbT0gUt+sXeOqoXBgNuUKI7TaObVwoEyWkpFgA== + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" + integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-transform-react-display-name" "^7.16.7" - "@babel/plugin-transform-react-jsx" "^7.17.12" - "@babel/plugin-transform-react-jsx-development" "^7.16.7" - "@babel/plugin-transform-react-pure-annotations" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-react-display-name" "^7.18.6" + "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/plugin-transform-react-jsx-development" "^7.18.6" + "@babel/plugin-transform-react-pure-annotations" "^7.18.6" "@babel/preset-typescript@^7.12.7": - version "7.17.12" - resolved "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.17.12.tgz#40269e0a0084d56fc5731b6c40febe1c9a4a3e8c" - integrity sha512-S1ViF8W2QwAKUGJXxP9NAfNaqGDdEBJKpYkxHf5Yy2C4NPPzXGeR3Lhk7G8xJaaLcFTRfNjVbtbVtm8Gb0mqvg== + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" + integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== dependencies: - "@babel/helper-plugin-utils" "^7.17.12" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-transform-typescript" "^7.17.12" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-typescript" "^7.18.6" "@babel/register@^7.12.1": - version "7.17.7" - resolved "https://registry.npmjs.org/@babel/register/-/register-7.17.7.tgz#5eef3e0f4afc07e25e847720e7b987ae33f08d0b" - integrity sha512-fg56SwvXRifootQEDQAu1mKdjh5uthPzdO0N6t358FktfL4XjAVXuH58ULoiW8mesxiOgNIrxiImqEwv0+hRRA== + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/register/-/register-7.18.9.tgz#1888b24bc28d5cc41c412feb015e9ff6b96e439c" + integrity sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw== dependencies: clone-deep "^4.0.1" find-cache-dir "^2.0.0" @@ -1060,43 +1064,44 @@ source-map-support "^0.5.16" "@babel/runtime@^7.0.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4": - version "7.18.3" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.3.tgz#c7b654b57f6f63cf7f8b418ac9ca04408c4579f4" - integrity sha512-38Y8f7YUhce/K7RMwTp7m0uCumpv9hZkitCbBClqQIow1qSbCvGkcegKOXpEWCQLfWmevgRiWokZ1GkpfhbZug== + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.12.7", "@babel/template@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" - integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== +"@babel/template@^7.12.7", "@babel/template@^7.18.10", "@babel/template@^7.18.6": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz#6f9134835970d1dbf0835c0d100c9f38de0c5e71" + integrity sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA== dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/parser" "^7.16.7" - "@babel/types" "^7.16.7" + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" -"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.8", "@babel/traverse@^7.18.0", "@babel/traverse@^7.18.2", "@babel/traverse@^7.18.5": - version "7.18.5" - resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz#94a8195ad9642801837988ab77f36e992d9a20cd" - integrity sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA== +"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.18.10", "@babel/traverse@^7.18.9": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.10.tgz#37ad97d1cb00efa869b91dd5d1950f8a6cf0cb08" + integrity sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g== dependencies: - "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.18.2" - "@babel/helper-environment-visitor" "^7.18.2" - "@babel/helper-function-name" "^7.17.9" - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.18.5" - "@babel/types" "^7.18.4" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.10" + "@babel/types" "^7.18.10" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.17.12", "@babel/types@^7.18.0", "@babel/types@^7.18.2", "@babel/types@^7.18.4", "@babel/types@^7.2.0", "@babel/types@^7.4.4": - version "7.18.4" - resolved "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz#27eae9b9fd18e9dccc3f9d6ad051336f307be354" - integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw== +"@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.18.10", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.2.0", "@babel/types@^7.4.4": + version "7.18.10" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz#4908e81b6b339ca7c6b7a555a5fc29446f26dde6" + integrity sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ== dependencies: - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-string-parser" "^7.18.10" + "@babel/helper-validator-identifier" "^7.18.6" to-fast-properties "^2.0.0" "@base2/pretty-print-object@1.0.1": @@ -1137,24 +1142,24 @@ "@jridgewell/set-array" "^1.0.0" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.1" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz#cf92a983c83466b8c0ce9124fadeaf09f7c66ea9" - integrity sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg== +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== dependencies: - "@jridgewell/set-array" "^1.0.0" + "@jridgewell/set-array" "^1.0.1" "@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/trace-mapping" "^0.3.9" "@jridgewell/resolve-uri@^3.0.3": - version "3.0.7" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz#30cd49820a962aff48c8fffc5cd760151fca61fe" - integrity sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA== + version "3.1.0" + resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== -"@jridgewell/set-array@^1.0.0": - version "1.1.1" - resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz#36a6acc93987adcf0ba50c66908bd0b70de8afea" - integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ== +"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== "@jridgewell/source-map@^0.3.2": version "0.3.2" @@ -1165,14 +1170,14 @@ "@jridgewell/trace-mapping" "^0.3.9" "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.13" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz#b6461fb0c2964356c469e115f504c95ad97ab88c" - integrity sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w== + version "1.4.14" + resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.13" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" - integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w== +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.7", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -1273,18 +1278,18 @@ source-map "^0.7.3" "@storybook/addon-a11y@^6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-6.5.9.tgz#191fb8ea9be4feee67fd11553b98ab56ecfc1295" - integrity sha512-jRiuJ2xlN8quVq2lOqpxqyuwAj8xLcgVBPy+Mf220u7AZmmbS/0sONyHKROfEBjJoHQAQYqn2vSAeuQZuTWyVA== + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/addon-a11y/-/addon-a11y-6.5.10.tgz#a907cbd3f1889ba367828435a58ecc9dac42f6ba" + integrity sha512-BnDbLg7YEAX1aEyiB+gDFYMXIbiSFH/M0CdwPCq7T7o8cqULKOHtQkndMja1soMxsqHAVH8AGvVVZ8VlaxaJ3Q== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/api" "6.5.9" - "@storybook/channels" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/components" "6.5.9" - "@storybook/core-events" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/api" "6.5.10" + "@storybook/channels" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/components" "6.5.10" + "@storybook/core-events" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.9" + "@storybook/theming" "6.5.10" axe-core "^4.2.0" core-js "^3.8.2" global "^4.4.0" @@ -1295,17 +1300,17 @@ util-deprecate "^1.0.2" "@storybook/addon-actions@^6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.5.9.tgz#d50d65631403e1a5b680961429d9c0d7bd383e68" - integrity sha512-wDYm3M1bN+zcYZV3Q24M03b/P8DDpvj1oSoY6VLlxDAi56h8qZB/voeIS2I6vWXOB79C5tbwljYNQO0GsufS0g== + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/addon-actions/-/addon-actions-6.5.10.tgz#83ec807a899e0412cf98037647f256c45cc32bf5" + integrity sha512-vpCnEu81fmtYzOf0QsRYoDuf9wXgVVl2VysE1dWRebRhIUDU0JurrthTnw322e38D4FzaoNGqZE7wnBYBohzZA== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/api" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/components" "6.5.9" - "@storybook/core-events" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/api" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/components" "6.5.10" + "@storybook/core-events" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.9" + "@storybook/theming" "6.5.10" core-js "^3.8.2" fast-deep-equal "^3.1.3" global "^4.4.0" @@ -1320,33 +1325,33 @@ uuid-browser "^3.1.0" "@storybook/addon-controls@^6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-6.5.9.tgz#8f6ef939c87b3dbad98f8bda7e124f0b34f668d2" - integrity sha512-VvjkgK32bGURKyWU2No6Q2B0RQZjLZk8D3neVNCnrWxwrl1G82StegxjRPn/UZm9+MZVPvTvI46nj1VdgOktnw== + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/addon-controls/-/addon-controls-6.5.10.tgz#275ddcd0f4dc1a107777b425417a8f252f52a91e" + integrity sha512-lC2y3XcolmQAJwFurIyGrynAHPWmfNtTCdu3rQBTVGwyxCoNwdOOeC2jV0BRqX2+CW6OHzJr9frNWXPSaZ8c4w== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/api" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/components" "6.5.9" - "@storybook/core-common" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/api" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/components" "6.5.10" + "@storybook/core-common" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/node-logger" "6.5.9" - "@storybook/store" "6.5.9" - "@storybook/theming" "6.5.9" + "@storybook/node-logger" "6.5.10" + "@storybook/store" "6.5.10" + "@storybook/theming" "6.5.10" core-js "^3.8.2" lodash "^4.17.21" ts-dedent "^2.0.0" "@storybook/addon-links@^6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-6.5.9.tgz#91cbca0c044796badf2498723fdd10dacea5748b" - integrity sha512-4BYC7pkxL3NLRnEgTA9jpIkObQKril+XFj1WtmY/lngF90vvK0Kc/TtvTA2/5tSgrHfxEuPevIdxMIyLJ4ejWQ== + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-6.5.10.tgz#f66568fbc84b942032ac2de85f799d69fcf77922" + integrity sha512-r3WzYIPz7WjHiaPObC2Tg6bHuZRBb/Kt/X+Eitw+jTqBel7ksvkO36tn81q8Eyj61qIdNQmUWAaX/0aewT0kLA== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/core-events" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/core-events" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/router" "6.5.9" + "@storybook/router" "6.5.10" "@types/qs" "^6.9.5" core-js "^3.8.2" global "^4.4.0" @@ -1356,17 +1361,17 @@ ts-dedent "^2.0.0" "@storybook/addon-storysource@^6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-6.5.9.tgz#8e5fb76b9314a69831a3b5e08e8570407c39de75" - integrity sha512-7KLw03mE1JJSJQrqNDftoVVp2BBq8wltd0qo7WHkpRVfir9dMO3g7Wy6S6UPsrb9th47ZjonwBJEc28GwAq0yg== + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/addon-storysource/-/addon-storysource-6.5.10.tgz#620619088657f247023d454dbaff3a2e1ccd7537" + integrity sha512-DM3UcbdqPfTBcpXr1AuzAs0DDTBnXMpXvOEkdoTTtGpbPIyA+J5KWeW1pAWqZlzI4k0UemJrAm2G6n/gGGBUiQ== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/api" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/components" "6.5.9" - "@storybook/router" "6.5.9" - "@storybook/source-loader" "6.5.9" - "@storybook/theming" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/api" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/components" "6.5.10" + "@storybook/router" "6.5.10" + "@storybook/source-loader" "6.5.10" + "@storybook/theming" "6.5.10" core-js "^3.8.2" estraverse "^5.2.0" loader-utils "^2.0.0" @@ -1374,7 +1379,24 @@ react-syntax-highlighter "^15.4.5" regenerator-runtime "^0.13.7" -"@storybook/addons@6.5.9", "@storybook/addons@^6.5.9": +"@storybook/addons@6.5.10", "@storybook/addons@^6.5.9": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/addons/-/addons-6.5.10.tgz#bff2f8fb8453e9df04fa6dbc41341fd05f4cdeba" + integrity sha512-VD4tBCQ23PkSeDoxuHcKy0RfhIs3oMYjBacOZx7d0bvOzK9WjPyvE2ysDAh7r/ceqnwmWHAScIpE+I1RU7gl+g== + dependencies: + "@storybook/api" "6.5.10" + "@storybook/channels" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/core-events" "6.5.10" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/router" "6.5.10" + "@storybook/theming" "6.5.10" + "@types/webpack-env" "^1.16.0" + core-js "^3.8.2" + global "^4.4.0" + regenerator-runtime "^0.13.7" + +"@storybook/addons@6.5.9": version "6.5.9" resolved "https://registry.npmjs.org/@storybook/addons/-/addons-6.5.9.tgz#5a9d7395c579a9cbc44dfc122362fb3c95dfb9d5" integrity sha512-adwdiXg+mntfPocLc1KXjZXyLgGk7Aac699Fwe+OUYPEC5tW347Rm/kFatcE556d42o5czcRiq3ZSIGWnm9ieQ== @@ -1391,6 +1413,29 @@ global "^4.4.0" regenerator-runtime "^0.13.7" +"@storybook/api@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/api/-/api-6.5.10.tgz#215623844648f0da2ac646fdcdd1345c2e1a8490" + integrity sha512-AkmgSPNEGdKp4oZA4KQ+RJsacw7GwfvjsVDnCkcXqS9zmSr/RNL0fhpcd60KKkmx/hGKPTDFpK3ZayxDrJ/h4A== + dependencies: + "@storybook/channels" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/core-events" "6.5.10" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/router" "6.5.10" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.5.10" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + store2 "^2.12.0" + telejson "^6.0.8" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + "@storybook/api@6.5.9": version "6.5.9" resolved "https://registry.npmjs.org/@storybook/api/-/api-6.5.9.tgz#303733214c9de0422d162f7c54ae05d088b89bf9" @@ -1414,28 +1459,28 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/builder-webpack4@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/builder-webpack4/-/builder-webpack4-6.5.9.tgz#4b37e1fa23a25aa4bfeaba640e5d318fcd511f95" - integrity sha512-YOeA4++9uRZ8Hog1wC60yjaxBOiI1FRQNtax7b9E7g+kP8UlSCPCGcv4gls9hFmzbzTOPfQTWnToA9Oa6jzRVw== +"@storybook/builder-webpack4@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/builder-webpack4/-/builder-webpack4-6.5.10.tgz#79e95323577a37349ab3c81193fa249ac5c50173" + integrity sha512-AoKjsCNoQQoZXYwBDxO8s+yVEd5FjBJAaysEuUTHq2fb81jwLrGcEOo6hjw4jqfugZQIzYUEjPazlvubS78zpw== dependencies: "@babel/core" "^7.12.10" - "@storybook/addons" "6.5.9" - "@storybook/api" "6.5.9" - "@storybook/channel-postmessage" "6.5.9" - "@storybook/channels" "6.5.9" - "@storybook/client-api" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/components" "6.5.9" - "@storybook/core-common" "6.5.9" - "@storybook/core-events" "6.5.9" - "@storybook/node-logger" "6.5.9" - "@storybook/preview-web" "6.5.9" - "@storybook/router" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/api" "6.5.10" + "@storybook/channel-postmessage" "6.5.10" + "@storybook/channels" "6.5.10" + "@storybook/client-api" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/components" "6.5.10" + "@storybook/core-common" "6.5.10" + "@storybook/core-events" "6.5.10" + "@storybook/node-logger" "6.5.10" + "@storybook/preview-web" "6.5.10" + "@storybook/router" "6.5.10" "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.9" - "@storybook/theming" "6.5.9" - "@storybook/ui" "6.5.9" + "@storybook/store" "6.5.10" + "@storybook/theming" "6.5.10" + "@storybook/ui" "6.5.10" "@types/node" "^14.0.10 || ^16.0.0" "@types/webpack" "^4.41.26" autoprefixer "^9.8.6" @@ -1468,26 +1513,26 @@ webpack-virtual-modules "^0.2.2" "@storybook/builder-webpack5@^6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-6.5.9.tgz#30b4e08622daff104bcccd015d3ee7902f99dd99" - integrity sha512-NUVZ4Qci6HWPuoH8U/zQkdBO5soGgu7QYrGC/LWU0tRfmmZxkjr7IUU14ppDpGPYgx3r7jkaQI1J/E1YEmSCWQ== + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/builder-webpack5/-/builder-webpack5-6.5.10.tgz#de78a8a262410bbe65eecc62f2beaed1fe44dd5d" + integrity sha512-Hcsm/TzGRXHndgQCftt+pzI7GQJRqAv8A8ie5b3aFcodhJfK0qzZsQD4Y4ZWxXh1I/xe5t74Kl2qUJ40PX+geA== dependencies: "@babel/core" "^7.12.10" - "@storybook/addons" "6.5.9" - "@storybook/api" "6.5.9" - "@storybook/channel-postmessage" "6.5.9" - "@storybook/channels" "6.5.9" - "@storybook/client-api" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/components" "6.5.9" - "@storybook/core-common" "6.5.9" - "@storybook/core-events" "6.5.9" - "@storybook/node-logger" "6.5.9" - "@storybook/preview-web" "6.5.9" - "@storybook/router" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/api" "6.5.10" + "@storybook/channel-postmessage" "6.5.10" + "@storybook/channels" "6.5.10" + "@storybook/client-api" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/components" "6.5.10" + "@storybook/core-common" "6.5.10" + "@storybook/core-events" "6.5.10" + "@storybook/node-logger" "6.5.10" + "@storybook/preview-web" "6.5.10" + "@storybook/router" "6.5.10" "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.9" - "@storybook/theming" "6.5.9" + "@storybook/store" "6.5.10" + "@storybook/theming" "6.5.10" "@types/node" "^14.0.10 || ^16.0.0" babel-loader "^8.0.0" babel-plugin-named-exports-order "^0.0.2" @@ -1511,30 +1556,39 @@ webpack-hot-middleware "^2.25.1" webpack-virtual-modules "^0.4.1" -"@storybook/channel-postmessage@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.5.9.tgz#9cf4530f0364cee0d5e58f92d6fb5ce98e10257b" - integrity sha512-pX/0R8UW7ezBhCrafRaL20OvMRcmESYvQQCDgjqSzJyHkcG51GOhsd6Ge93eJ6QvRMm9+w0Zs93N2VKjVtz0Qw== +"@storybook/channel-postmessage@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/channel-postmessage/-/channel-postmessage-6.5.10.tgz#be8971b4b7f91b664bb2c6965fdfb073d541a03e" + integrity sha512-t9PTA0UzFvYa3IlOfpBOolfrRMPTjUMIeCQ6FNyM0aj5GqLKSvoQzP8NeoRpIrvyf6ljFKKdaMaZ3fiCvh45ag== dependencies: - "@storybook/channels" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/core-events" "6.5.9" + "@storybook/channels" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/core-events" "6.5.10" core-js "^3.8.2" global "^4.4.0" qs "^6.10.0" telejson "^6.0.8" -"@storybook/channel-websocket@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-6.5.9.tgz#6b7a0127fec58ee5be4f6aebcf460adc564f2f34" - integrity sha512-xtHvSNwuOhkgALwVshKWsoFhDmuvcosdYfxcfFGEiYKXIu46tRS5ZXmpmgEC/0JAVkVoFj5nL8bV7IY5np6oaA== +"@storybook/channel-websocket@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/channel-websocket/-/channel-websocket-6.5.10.tgz#bd1316a9b555229b215e5054a76b57c503dd8adc" + integrity sha512-RTXMZbMWCS3xU+4GVIdfnUXsKcwg/WTozy88/5OxaKjGw6KgRedqLAQJKJ6Y5XlnwIcWelirkHj/COwTTXhbPg== dependencies: - "@storybook/channels" "6.5.9" - "@storybook/client-logger" "6.5.9" + "@storybook/channels" "6.5.10" + "@storybook/client-logger" "6.5.10" core-js "^3.8.2" global "^4.4.0" telejson "^6.0.8" +"@storybook/channels@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/channels/-/channels-6.5.10.tgz#fca5b0d1ea8d30b022e805301ed436407c867ac4" + integrity sha512-lo26YZ6kWpHXLhuHJF4P/bICY7jD/rXEZqReKtGOSk1Lv99/xvG6pqmcy3hWLf3v3Dy/8otjRPSR7izFVIIZgQ== + dependencies: + core-js "^3.8.2" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + "@storybook/channels@6.5.9": version "6.5.9" resolved "https://registry.npmjs.org/@storybook/channels/-/channels-6.5.9.tgz#abfab89a6587a2688e9926d4aafeb11c9d8b2e79" @@ -1544,18 +1598,18 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/client-api@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.5.9.tgz#3e4a8ec1d277fd81325c5d959c553161a85fa182" - integrity sha512-pc7JKJoWLesixUKvG2nV36HukUuYoGRyAgD3PpIV7qSBS4JixqZ3VAHFUtqV1UzfOSQTovLSl4a0rIRnpie6gA== +"@storybook/client-api@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/client-api/-/client-api-6.5.10.tgz#0bc3f68ce014ce1ffd560472a893ba04be370f09" + integrity sha512-3wBWZl3NvMFgMovgEh+euiARAT2FXzpvTF4Q1gerGMNNDlrGxHnFvSuy4FHg/irtOGLa4yLz43ULFbYtpKw0Lg== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/channel-postmessage" "6.5.9" - "@storybook/channels" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/core-events" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/channel-postmessage" "6.5.10" + "@storybook/channels" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/core-events" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.9" + "@storybook/store" "6.5.10" "@types/qs" "^6.9.5" "@types/webpack-env" "^1.16.0" core-js "^3.8.2" @@ -1570,6 +1624,14 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" +"@storybook/client-logger@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.5.10.tgz#cfea823a5b8444409daa74f854c5d05367986b34" + integrity sha512-/xA0MHOevXev68hyLMQw8Qo8KczSIdXOxliAgrycMTkDmw5eKeA8TP7B8zP3wGuq/e3MrdD9/8MWhb/IQBNC3w== + dependencies: + core-js "^3.8.2" + global "^4.4.0" + "@storybook/client-logger@6.5.9", "@storybook/client-logger@^6.4.0": version "6.5.9" resolved "https://registry.npmjs.org/@storybook/client-logger/-/client-logger-6.5.9.tgz#dc1669abe8c45af1cc38f74c6f4b15ff33e63014" @@ -1578,37 +1640,35 @@ core-js "^3.8.2" global "^4.4.0" -"@storybook/components@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/components/-/components-6.5.9.tgz#97e07ffe11ab76c01ccee380888991bd161f75b2" - integrity sha512-BhfX980O9zn/1J4FNMeDo8ZvL1m5Ml3T4HRpfYmEBnf8oW5b5BeF6S2K2cwFStZRjWqm1feUcwNpZxCBVMkQnQ== +"@storybook/components@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/components/-/components-6.5.10.tgz#268e1269bc3d262f7dcec13f96c3b844919687b8" + integrity sha512-9OhgB8YQfGwOKjo/N96N5mrtJ6qDVVoEM1zuhea32tJUd2eYf0aSWpryA9VnOM0V1q/8DAoCg5rPBMYWMBU5uw== dependencies: - "@storybook/client-logger" "6.5.9" + "@storybook/client-logger" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.9" - "@types/react-syntax-highlighter" "11.0.5" + "@storybook/theming" "6.5.10" core-js "^3.8.2" memoizerific "^1.11.3" qs "^6.10.0" - react-syntax-highlighter "^15.4.5" regenerator-runtime "^0.13.7" util-deprecate "^1.0.2" -"@storybook/core-client@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/core-client/-/core-client-6.5.9.tgz#ea6035d1c90d2c68e860e3cf629979491856cd88" - integrity sha512-LY0QbhShowO+PQx3gao3wdVjpKMH1AaSLmuI95FrcjoMmSXGf96jVLKQp9mJRGeHIsAa93EQBYuCihZycM3Kbg== +"@storybook/core-client@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/core-client/-/core-client-6.5.10.tgz#90c86923236c8efff33d454a0dc552f6df4346b1" + integrity sha512-THsIjNrOrampTl0Lgfjvfjk1JnktKb4CQLOM80KpQb4cjDqorBjJmErzUkUQ2y3fXvrDmQ/kUREkShET4XEdtA== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/channel-postmessage" "6.5.9" - "@storybook/channel-websocket" "6.5.9" - "@storybook/client-api" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/core-events" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/channel-postmessage" "6.5.10" + "@storybook/channel-websocket" "6.5.10" + "@storybook/client-api" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/core-events" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/preview-web" "6.5.9" - "@storybook/store" "6.5.9" - "@storybook/ui" "6.5.9" + "@storybook/preview-web" "6.5.10" + "@storybook/store" "6.5.10" + "@storybook/ui" "6.5.10" airbnb-js-shims "^2.2.1" ansi-to-html "^0.6.11" core-js "^3.8.2" @@ -1620,10 +1680,10 @@ unfetch "^4.2.0" util-deprecate "^1.0.2" -"@storybook/core-common@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/core-common/-/core-common-6.5.9.tgz#7ca8258ea2634b1d64695c1e4262f71cc7457989" - integrity sha512-NxOK0mrOCo0TWZ7Npc5HU66EKoRHlrtg18/ZixblLDWQMIqY9XCck8K1kJ8QYpYCHla+aHIsYUArFe2vhlEfZA== +"@storybook/core-common@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/core-common/-/core-common-6.5.10.tgz#6b93449548b0890f5c68d89f0ca78e092026182c" + integrity sha512-Bx+VKkfWdrAmD8T51Sjq/mMhRaiapBHcpG4cU5bc3DMbg+LF2/yrgqv/cjVu+m5gHAzYCac5D7gqzBgvG7Myww== dependencies: "@babel/core" "^7.12.10" "@babel/plugin-proposal-class-properties" "^7.12.1" @@ -1647,7 +1707,7 @@ "@babel/preset-react" "^7.12.10" "@babel/preset-typescript" "^7.12.7" "@babel/register" "^7.12.1" - "@storybook/node-logger" "6.5.9" + "@storybook/node-logger" "6.5.10" "@storybook/semver" "^7.3.2" "@types/node" "^14.0.10 || ^16.0.0" "@types/pretty-hrtime" "^1.0.0" @@ -1676,6 +1736,13 @@ util-deprecate "^1.0.2" webpack "4" +"@storybook/core-events@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.5.10.tgz#66d87c8ea18db8e448018a16a3d0198ddbcbc683" + integrity sha512-EVb1gO1172klVIAABLOoigFMx0V88uctY0K/qVCO8n6v+wd2+0Ccn63kl+gTxsAC3WZ8XhXh9q2w5ImHklVECw== + dependencies: + core-js "^3.8.2" + "@storybook/core-events@6.5.9": version "6.5.9" resolved "https://registry.npmjs.org/@storybook/core-events/-/core-events-6.5.9.tgz#5b0783c7d22a586c0f5e927a61fe1b1223e19637" @@ -1683,23 +1750,23 @@ dependencies: core-js "^3.8.2" -"@storybook/core-server@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/core-server/-/core-server-6.5.9.tgz#749a881c1a81d7cf1a69f3782c06a7f0c39a505c" - integrity sha512-YeePGUrd5fQPvGzMhowh124KrcZURFpFXg1VB0Op3ESqCIsInoMZeObci4Gc+binMXC7vcv7aw3EwSLU37qJzQ== +"@storybook/core-server@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/core-server/-/core-server-6.5.10.tgz#ada3d647833c02cb8c742281c1f314ff866f96f8" + integrity sha512-jqwpA0ccA8X5ck4esWBid04+cEIVqirdAcqJeNb9IZAD+bRreO4Im8ilzr7jc5AmQ9fkqHs2NByFKh9TITp8NQ== dependencies: "@discoveryjs/json-ext" "^0.5.3" - "@storybook/builder-webpack4" "6.5.9" - "@storybook/core-client" "6.5.9" - "@storybook/core-common" "6.5.9" - "@storybook/core-events" "6.5.9" + "@storybook/builder-webpack4" "6.5.10" + "@storybook/core-client" "6.5.10" + "@storybook/core-common" "6.5.10" + "@storybook/core-events" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/csf-tools" "6.5.9" - "@storybook/manager-webpack4" "6.5.9" - "@storybook/node-logger" "6.5.9" + "@storybook/csf-tools" "6.5.10" + "@storybook/manager-webpack4" "6.5.10" + "@storybook/node-logger" "6.5.10" "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.9" - "@storybook/telemetry" "6.5.9" + "@storybook/store" "6.5.10" + "@storybook/telemetry" "6.5.10" "@types/node" "^14.0.10 || ^16.0.0" "@types/node-fetch" "^2.5.7" "@types/pretty-hrtime" "^1.0.0" @@ -1734,18 +1801,18 @@ ws "^8.2.3" x-default-browser "^0.4.0" -"@storybook/core@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/core/-/core-6.5.9.tgz#da4f237391d99aed1228323f24b335cafbdf3499" - integrity sha512-Mt3TTQnjQt2/pa60A+bqDsAOrYpohapdtt4DDZEbS8h0V6u11KyYYh3w7FCySlL+sPEyogj63l5Ec76Jah3l2w== +"@storybook/core@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/core/-/core-6.5.10.tgz#15ec8be85943251e25c2c24e80e20dcacc4fed65" + integrity sha512-K86yYa0tYlMxADlwQTculYvPROokQau09SCVqpsLg3wJCTvYFL4+SIqcYoyBSbFmHOdnYbJgPydjN33MYLiOZQ== dependencies: - "@storybook/core-client" "6.5.9" - "@storybook/core-server" "6.5.9" + "@storybook/core-client" "6.5.10" + "@storybook/core-server" "6.5.10" -"@storybook/csf-tools@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-6.5.9.tgz#8e01df2305b53e228229f0b45ada3720e6e42a1c" - integrity sha512-RAdhsO2XmEDyWy0qNQvdKMLeIZAuyfD+tYlUwBHRU6DbByDucvwgMOGy5dF97YNJFmyo93EUYJzXjUrJs3U1LQ== +"@storybook/csf-tools@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/csf-tools/-/csf-tools-6.5.10.tgz#ae6f1ebd4951e8978c8fe3e08ddd2bd269bf922b" + integrity sha512-H77kZQEisu7+skzeIbNZwmE09OqLjwJTeFhLN1pcjxKVa30LEI3pBHcNBxVKqgxl+Yg3KkB7W/ArLO2N+i2ohw== dependencies: "@babel/core" "^7.12.10" "@babel/generator" "^7.12.11" @@ -1769,14 +1836,14 @@ dependencies: lodash "^4.17.15" -"@storybook/docs-tools@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-6.5.9.tgz#5ff304f881e972ce14923a5ffcfed3f052094889" - integrity sha512-UoTaXLvec8x+q+4oYIk/t8DBju9C3ZTGklqOxDIt+0kS3TFAqEgI3JhKXqQOXgN5zDcvLVSxi8dbVAeSxk2ktA== +"@storybook/docs-tools@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/docs-tools/-/docs-tools-6.5.10.tgz#30baa62c1ca3a18b13625b6b305e23e39f404416" + integrity sha512-/bvYgOO+CxMEcHifkjJg0A60OTGOhcjGxnsB1h0gJuxMrqA/7Qwc108bFmPiX0eiD1BovFkZLJV4O6OY7zP5Vw== dependencies: "@babel/core" "^7.12.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.9" + "@storybook/store" "6.5.10" core-js "^3.8.2" doctrine "^3.0.0" lodash "^4.17.21" @@ -1793,20 +1860,20 @@ core-js "^3.8.2" global "^4.4.0" -"@storybook/manager-webpack4@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/manager-webpack4/-/manager-webpack4-6.5.9.tgz#c75d2cced4550c8a786f00b0e57b203d613e706c" - integrity sha512-49LZlHqWc7zj9tQfOOANixPYmLxqWTTZceA6DSXnKd9xDiO2Gl23Y+l/CSPXNZGDB8QFAwpimwqyKJj/NLH45A== +"@storybook/manager-webpack4@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/manager-webpack4/-/manager-webpack4-6.5.10.tgz#41bae252b863484f293954ef2d2dc80bf3e028f1" + integrity sha512-N/TlNDhuhARuFipR/ZJ/xEVESz23iIbCsZ4VNehLHm8PpiGlQUehk+jMjWmz5XV0bJItwjRclY+CU3GjZKblfQ== dependencies: "@babel/core" "^7.12.10" "@babel/plugin-transform-template-literals" "^7.12.1" "@babel/preset-react" "^7.12.10" - "@storybook/addons" "6.5.9" - "@storybook/core-client" "6.5.9" - "@storybook/core-common" "6.5.9" - "@storybook/node-logger" "6.5.9" - "@storybook/theming" "6.5.9" - "@storybook/ui" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/core-client" "6.5.10" + "@storybook/core-common" "6.5.10" + "@storybook/node-logger" "6.5.10" + "@storybook/theming" "6.5.10" + "@storybook/ui" "6.5.10" "@types/node" "^14.0.10 || ^16.0.0" "@types/webpack" "^4.41.26" babel-loader "^8.0.0" @@ -1835,19 +1902,19 @@ webpack-virtual-modules "^0.2.2" "@storybook/manager-webpack5@^6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/manager-webpack5/-/manager-webpack5-6.5.9.tgz#ce9dd6ea6298ab426b111f170c23deea7085ba08" - integrity sha512-J1GamphSsaZLNBEhn1awgxzOS8KfvzrHtVlAm2VHwW7j1E1DItROFJhGCgduYYuBiN9eqm+KIYrxcr6cRuoolQ== + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/manager-webpack5/-/manager-webpack5-6.5.10.tgz#dff8e53615906284b68df013935e8a6234ddaafe" + integrity sha512-uRo+6e5MiVOtyFVMYIKVqvpDveCjHyzXBfetSYR7rKEZoaDMEnLLiuF7DIH12lzxwmzCJ1gIc4lf5HFiTMNkgw== dependencies: "@babel/core" "^7.12.10" "@babel/plugin-transform-template-literals" "^7.12.1" "@babel/preset-react" "^7.12.10" - "@storybook/addons" "6.5.9" - "@storybook/core-client" "6.5.9" - "@storybook/core-common" "6.5.9" - "@storybook/node-logger" "6.5.9" - "@storybook/theming" "6.5.9" - "@storybook/ui" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/core-client" "6.5.10" + "@storybook/core-common" "6.5.10" + "@storybook/node-logger" "6.5.10" + "@storybook/theming" "6.5.10" + "@storybook/ui" "6.5.10" "@types/node" "^14.0.10 || ^16.0.0" babel-loader "^8.0.0" case-sensitive-paths-webpack-plugin "^2.3.0" @@ -1889,10 +1956,10 @@ prettier ">=2.2.1 <=2.3.0" ts-dedent "^2.0.0" -"@storybook/node-logger@6.5.9", "@storybook/node-logger@^6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.5.9.tgz#129cfe0d0f79cab4f6a2ba194d39516680b1626f" - integrity sha512-nZZNZG2Wtwv6Trxi3FrnIqUmB55xO+X/WQGPT5iKlqNjdRIu/T72mE7addcp4rbuWCQfZUhcDDGpBOwKtBxaGg== +"@storybook/node-logger@6.5.10", "@storybook/node-logger@^6.5.9": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/node-logger/-/node-logger-6.5.10.tgz#bce4c04009c4b62d6d2fb617176d7ef0084e9e89" + integrity sha512-bYswXIKV7Stru8vYfkjUMNN8UhF7Qg7NRsUvG5Djt5lLIae1XmUIgnH40mU/nW4X4BSfcR9MKxsSsngvn2WmQg== dependencies: "@types/npmlog" "^4.1.2" chalk "^4.1.0" @@ -1900,17 +1967,17 @@ npmlog "^5.0.1" pretty-hrtime "^1.0.3" -"@storybook/preview-web@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/preview-web/-/preview-web-6.5.9.tgz#557d919e6df50d66259521aa36ebf4055bbd236e" - integrity sha512-4eMrO2HJyZUYyL/j+gUaDvry6iGedshwT5MQqe7J9FaA+Q2pNARQRB1X53f410w7S4sObRmYIAIluWPYdWym9w== +"@storybook/preview-web@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/preview-web/-/preview-web-6.5.10.tgz#81bf5d3f5fca9e26099c057206bd8e684225989b" + integrity sha512-sTC/o5gkvALOtcNgtApGKGN9EavvSxRHBeBh+5BQjV2qQ8ap+26RsfUizNBECAa2Jrn4osaDYn9HRhJLFL69WA== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/channel-postmessage" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/core-events" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/channel-postmessage" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/core-events" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.9" + "@storybook/store" "6.5.10" ansi-to-html "^0.6.11" core-js "^3.8.2" global "^4.4.0" @@ -1936,23 +2003,23 @@ tslib "^2.0.0" "@storybook/react@^6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/react/-/react-6.5.9.tgz#687ec1f6b785822a392b7ac115b61800f69fb7cd" - integrity sha512-Rp+QaTQAzxJhwuzJXVd49mnIBLQRlF8llTxPT2YoGHdrGkku/zl/HblQ6H2yzEf15367VyzaAv/BpLsO9Jlfxg== + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/react/-/react-6.5.10.tgz#6e9f5cf5e4c81d966774c08c87fb2414052db454" + integrity sha512-m8S1qQrwA7pDGwdKEvL6LV3YKvSzVUY297Fq+xcTU3irnAy4sHDuFoLqV6Mi1510mErK1r8+rf+0R5rEXB219g== dependencies: "@babel/preset-flow" "^7.12.1" "@babel/preset-react" "^7.12.10" "@pmmmwh/react-refresh-webpack-plugin" "^0.5.3" - "@storybook/addons" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/core" "6.5.9" - "@storybook/core-common" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/core" "6.5.10" + "@storybook/core-common" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/docs-tools" "6.5.9" - "@storybook/node-logger" "6.5.9" + "@storybook/docs-tools" "6.5.10" + "@storybook/node-logger" "6.5.10" "@storybook/react-docgen-typescript-plugin" "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0" "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.9" + "@storybook/store" "6.5.10" "@types/estree" "^0.0.51" "@types/node" "^14.14.20 || ^16.0.0" "@types/webpack-env" "^1.16.0" @@ -1976,6 +2043,17 @@ util-deprecate "^1.0.2" webpack ">=4.43.0 <6.0.0" +"@storybook/router@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/router/-/router-6.5.10.tgz#b0c342e080c1d2b5344603bc43a6c75734a4a879" + integrity sha512-O+vNW/eEpYFF8eCg5jZjNQ6q2DKQVxqDRPCy9pJdEbvavMDZn6AFYgVK+VJe5F4211WW2yncOu922xObCxXJYg== + dependencies: + "@storybook/client-logger" "6.5.10" + core-js "^3.8.2" + memoizerific "^1.11.3" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + "@storybook/router@6.5.9": version "6.5.9" resolved "https://registry.npmjs.org/@storybook/router/-/router-6.5.9.tgz#4740248f8517425b2056273fb366ace8a17c65e8" @@ -1995,13 +2073,13 @@ core-js "^3.6.5" find-up "^4.1.0" -"@storybook/source-loader@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-6.5.9.tgz#7b6f065c6a6108c4b4ca7e45bfd78707373d84ac" - integrity sha512-H03nFKaP6borfWMTTa9igBA+Jm2ph+FoVJImWC/X+LAmLSJYYSXuqSgmiZ/DZvbjxS4k8vccE2HXogne1IvaRA== +"@storybook/source-loader@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/source-loader/-/source-loader-6.5.10.tgz#f62b4c7b1933976a20913ddc149d55026ef4c872" + integrity sha512-1RxxRumpjs8VUUwES9LId+cuNQnixhZAcwCxd6jaKkTZbjiQCtAhXX6DBTjJGV1u/JnCsqEp5b1wB8j/EioNHw== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/client-logger" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/client-logger" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" core-js "^3.8.2" estraverse "^5.2.0" @@ -2011,14 +2089,14 @@ prettier ">=2.2.1 <=2.3.0" regenerator-runtime "^0.13.7" -"@storybook/store@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/store/-/store-6.5.9.tgz#dc9963fc013636569082bd8f7200804866373735" - integrity sha512-80pcDTcCwK6wUA63aWOp13urI77jfipIVee9mpVvbNyfrNN8kGv1BS0z/JHDxuV6rC4g7LG1fb+BurR0yki7BA== +"@storybook/store@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/store/-/store-6.5.10.tgz#85df17a8d57af0cba3934b3c6046537e2bca9abd" + integrity sha512-RswrSYh2IiKkytFPxP9AvP+hekjrvHK2ILvyDk2ZgduCN4n5ivsekOb+N3M2t+dq1eLuW9or5n2T4OWwAwjxxQ== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/core-events" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/core-events" "6.5.10" "@storybook/csf" "0.0.2--canary.4566f4d.1" core-js "^3.8.2" fast-deep-equal "^3.1.3" @@ -2032,13 +2110,13 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/telemetry@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-6.5.9.tgz#8e1e0d4a89fc2387620045e5ea96c109d16a7247" - integrity sha512-JluoHCRhHAr4X0eUNVBSBi1JIBA92404Tu1TPdbN7x6gCZxHXXPTSUTAnspXp/21cTdMhY2x+kfZQ8fmlGK4MQ== +"@storybook/telemetry@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/telemetry/-/telemetry-6.5.10.tgz#742b05a55dfe8470ce4cb371f3f3f2c02f96e816" + integrity sha512-+M5HILDFS8nDumLxeSeAwi1MTzIuV6UWzV4yB2wcsEXOBTdplcl9oYqFKtlst78oOIdGtpPYxYfivDlqxC2K4g== dependencies: - "@storybook/client-logger" "6.5.9" - "@storybook/core-common" "6.5.9" + "@storybook/client-logger" "6.5.10" + "@storybook/core-common" "6.5.10" chalk "^4.1.0" core-js "^3.8.2" detect-package-manager "^2.0.1" @@ -2061,6 +2139,16 @@ "@testing-library/user-event" "^13.2.1" ts-dedent "^2.2.0" +"@storybook/theming@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.10.tgz#052100979c1270fc8f60653c1a13a6f047318109" + integrity sha512-BvTQBBcSEwKKcsVmF+Ol6v0RIQUr+bxP7gb10wtfBd23mZTEFA0C1N5FnZr/dDeiBKG1pvf1UKvoYA731y0BsA== + dependencies: + "@storybook/client-logger" "6.5.10" + core-js "^3.8.2" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + "@storybook/theming@6.5.9": version "6.5.9" resolved "https://registry.npmjs.org/@storybook/theming/-/theming-6.5.9.tgz#13f60a3a3cd73ceb5caf9f188e1627e79f1891aa" @@ -2071,20 +2159,20 @@ memoizerific "^1.11.3" regenerator-runtime "^0.13.7" -"@storybook/ui@6.5.9": - version "6.5.9" - resolved "https://registry.npmjs.org/@storybook/ui/-/ui-6.5.9.tgz#41e59279323cccc0d613974ec9782d797220c8a7" - integrity sha512-ryuPxJgtbb0gPXKGgGAUC+Z185xGAd1IvQ0jM5fJ0SisHXI8jteG3RaWhntOehi9qCg+64Vv6eH/cj9QYNHt1Q== +"@storybook/ui@6.5.10": + version "6.5.10" + resolved "https://registry.npmjs.org/@storybook/ui/-/ui-6.5.10.tgz#f56095a1a39ae5a203f2ac7f3dba86341a5927d5" + integrity sha512-6iaoaRAiTqB1inTw35vao+5hjcDE0Qa0A3a9ZIeNa6yHvpB1k0lO/N/0PMrRdVvySYpXVD1iry4z4QYdo1rU+w== dependencies: - "@storybook/addons" "6.5.9" - "@storybook/api" "6.5.9" - "@storybook/channels" "6.5.9" - "@storybook/client-logger" "6.5.9" - "@storybook/components" "6.5.9" - "@storybook/core-events" "6.5.9" - "@storybook/router" "6.5.9" + "@storybook/addons" "6.5.10" + "@storybook/api" "6.5.10" + "@storybook/channels" "6.5.10" + "@storybook/client-logger" "6.5.10" + "@storybook/components" "6.5.10" + "@storybook/core-events" "6.5.10" + "@storybook/router" "6.5.10" "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.5.9" + "@storybook/theming" "6.5.10" core-js "^3.8.2" memoizerific "^1.11.3" qs "^6.10.0" @@ -2125,22 +2213,27 @@ integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig== "@types/eslint-scope@^3.7.3": - version "3.7.3" - resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" - integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== + version "3.7.4" + resolved "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" + integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== dependencies: "@types/eslint" "*" "@types/estree" "*" "@types/eslint@*": - version "8.4.3" - resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.3.tgz#5c92815a3838b1985c90034cd85f26f59d9d0ece" - integrity sha512-YP1S7YJRMPs+7KZKDb9G63n8YejIwW9BALq7a5j2+H4yl6iOv9CB29edho+cuFRrvmJbbaH2yiVChKLJVysDGw== + version "8.4.5" + resolved "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz#acdfb7dd36b91cc5d812d7c093811a8f3d9b31e4" + integrity sha512-dhsC09y1gpJWnK+Ff4SGvCuSnk9DaU0BJZSzOwa6GVSg65XtTugLBITDAAzRU5duGBoXBHpdR/9jHGxJjNflJQ== dependencies: "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^0.0.51": +"@types/estree@*": + version "1.0.0" + resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" + integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== + +"@types/estree@^0.0.51": version "0.0.51" resolved "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== @@ -2203,22 +2296,22 @@ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/node-fetch@^2.5.7": - version "2.6.1" - resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.1.tgz#8f127c50481db65886800ef496f20bbf15518975" - integrity sha512-oMqjURCaxoSIsHSr1E47QHzbmzNR5rK8McHuNb11BOM9cHcIK3Avy0s/b2JlXHoQGTYS3NsvWzV1M0iK7l0wbA== + version "2.6.2" + resolved "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" + integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A== dependencies: "@types/node" "*" form-data "^3.0.0" "@types/node@*": - version "17.0.44" - resolved "https://registry.npmjs.org/@types/node/-/node-17.0.44.tgz#16dd0bb5338f016d8ca10631789f0d0612fe5d5b" - integrity sha512-gWYiOlu6Y4oyLYBvsJAPlwHbC8H4tX+tLsHy6Ee976wedwwZKrG2hFl3Y/HiH6bIyLTbDWQexQF/ohwKkOpUCg== + version "18.6.3" + resolved "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz#4e4a95b6fe44014563ceb514b2598b3e623d1c98" + integrity sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg== "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0": - version "16.11.41" - resolved "https://registry.npmjs.org/@types/node/-/node-16.11.41.tgz#88eb485b1bfdb4c224d878b7832239536aa2f813" - integrity sha512-mqoYK2TnVjdkGk8qXAVGc/x9nSaTpSrFaGFm43BUH3IdoBV0nta6hYaGmdOvIMlbHJbUEVen3gvwpwovAZKNdQ== + version "16.11.47" + resolved "https://registry.npmjs.org/@types/node/-/node-16.11.47.tgz#efa9e3e0f72e7aa6a138055dace7437a83d9f91c" + integrity sha512-fpP+jk2zJ4VW66+wAMFoBJlx1bxmBKx4DUFf68UHgdGCOuyUTDlLWqsaNPJh7xhNDykyJ9eIzAygilP/4WoN8g== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -2245,37 +2338,11 @@ resolved "https://registry.npmjs.org/@types/pretty-hrtime/-/pretty-hrtime-1.0.1.tgz#72a26101dc567b0d68fd956cf42314556e42d601" integrity sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ== -"@types/prop-types@*": - version "15.7.5" - resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" - integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== - "@types/qs@^6.9.5": version "6.9.7" resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== -"@types/react-syntax-highlighter@11.0.5": - version "11.0.5" - resolved "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.5.tgz#0d546261b4021e1f9d85b50401c0a42acb106087" - integrity sha512-VIOi9i2Oj5XsmWWoB72p3KlZoEbdRAcechJa8Ztebw7bDl2YmR+odxIqhtJGp1q2EozHs02US+gzxJ9nuf56qg== - dependencies: - "@types/react" "*" - -"@types/react@*": - version "18.0.12" - resolved "https://registry.npmjs.org/@types/react/-/react-18.0.12.tgz#cdaa209d0a542b3fcf69cf31a03976ec4cdd8840" - integrity sha512-duF1OTASSBQtcigUvhuiTB1Ya3OvSy+xORCiEf20H0P0lzx+/KeVsA99U5UjLXSbyo1DRJDlLKqTeM1ngosqtg== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/scheduler@*": - version "0.16.2" - resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" - integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== - "@types/source-list-map@*": version "0.1.2" resolved "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" @@ -2483,10 +2550,10 @@ acorn@^7.4.1: resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.4.1, acorn@^8.5.0: - version "8.7.1" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" - integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== +acorn@^8.5.0, acorn@^8.7.1: + version "8.8.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== address@^1.0.1: version "1.2.0" @@ -2774,9 +2841,9 @@ autoprefixer@^9.8.6: postcss-value-parser "^4.1.0" axe-core@^4.2.0: - version "4.4.2" - resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz#dcf7fb6dea866166c3eab33d68208afe4d5f670c" - integrity sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA== + version "4.4.3" + resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f" + integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w== babel-loader@^8.0.0: version "8.2.5" @@ -2829,13 +2896,13 @@ babel-plugin-named-exports-order@^0.0.2: resolved "https://registry.npmjs.org/babel-plugin-named-exports-order/-/babel-plugin-named-exports-order-0.0.2.tgz#ae14909521cf9606094a2048239d69847540cb09" integrity sha512-OgOYHOLoRK+/mvXU9imKHlG6GkPLYrUCvFXG/CM93R/aNNO8pOOF4aS+S8CCHMDQoNSeiOYEZb/G6RwL95Jktw== -babel-plugin-polyfill-corejs2@^0.3.0: - version "0.3.1" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" - integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== +babel-plugin-polyfill-corejs2@^0.3.2: + version "0.3.2" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz#e4c31d4c89b56f3cf85b92558954c66b54bd972d" + integrity sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q== dependencies: - "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.3.1" + "@babel/compat-data" "^7.17.7" + "@babel/helper-define-polyfill-provider" "^0.3.2" semver "^6.1.1" babel-plugin-polyfill-corejs3@^0.1.0: @@ -2846,20 +2913,20 @@ babel-plugin-polyfill-corejs3@^0.1.0: "@babel/helper-define-polyfill-provider" "^0.1.5" core-js-compat "^3.8.1" -babel-plugin-polyfill-corejs3@^0.5.0: - version "0.5.2" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" - integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== +babel-plugin-polyfill-corejs3@^0.5.3: + version "0.5.3" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz#d7e09c9a899079d71a8b670c6181af56ec19c5c7" + integrity sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" + "@babel/helper-define-polyfill-provider" "^0.3.2" core-js-compat "^3.21.0" -babel-plugin-polyfill-regenerator@^0.3.0: - version "0.3.1" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" - integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== +babel-plugin-polyfill-regenerator@^0.4.0: + version "0.4.0" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz#8f51809b6d5883e07e71548d75966ff7635527fe" + integrity sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.3.1" + "@babel/helper-define-polyfill-provider" "^0.3.2" babel-plugin-react-docgen@^4.2.1: version "4.2.1" @@ -3000,16 +3067,15 @@ browser-assert@^1.2.1: resolved "https://registry.npmjs.org/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== -browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.20.2, browserslist@^4.20.4: - version "4.20.4" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz#98096c9042af689ee1e0271333dbc564b8ce4477" - integrity sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw== +browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.20.2, browserslist@^4.21.3: + version "4.21.3" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz#5df277694eb3c48bc5c4b05af3e8b7e09c5a6d1a" + integrity sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ== dependencies: - caniuse-lite "^1.0.30001349" - electron-to-chromium "^1.4.147" - escalade "^3.1.1" - node-releases "^2.0.5" - picocolors "^1.0.0" + caniuse-lite "^1.0.30001370" + electron-to-chromium "^1.4.202" + node-releases "^2.0.6" + update-browserslist-db "^1.0.5" buffer-from@^1.0.0: version "1.1.2" @@ -3027,9 +3093,9 @@ bytes@3.1.2: integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== c8@^7.6.0: - version "7.11.3" - resolved "https://registry.npmjs.org/c8/-/c8-7.11.3.tgz#88c8459c1952ed4f701b619493c9ae732b057163" - integrity sha512-6YBmsaNmqRm9OS3ZbIiL2EZgi1+Xc4O24jL3vMYGE6idixYuGdy76rIfIdltSKDj9DpLNrcXSonUTR1miBD0wA== + version "7.12.0" + resolved "https://registry.npmjs.org/c8/-/c8-7.12.0.tgz#402db1c1af4af5249153535d1c84ad70c5c96b14" + integrity sha512-CtgQrHOkyxr5koX1wEUmN/5cfDa2ckbHRA4Gy5LAL0zaCFtVWJS5++n+w4/sr2GWGerBxgTjpKeDclk/Qk6W/A== dependencies: "@bcoe/v8-coverage" "^0.2.3" "@istanbuljs/schema" "^0.1.3" @@ -3137,10 +3203,10 @@ camelcase@^6.2.0: resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001349: - version "1.0.30001354" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001354.tgz#95c5efdb64148bb4870771749b9a619304755ce5" - integrity sha512-mImKeCkyGDAHNywYFA4bqnLAzTUvVkqPvhY4DV47X+Gl2c5Z8c3KNETnXp14GQt11LvxE8AwjzGxJ+rsikiOzg== +caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001370: + version "1.0.30001373" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz#2dc3bc3bfcb5d5a929bec11300883040d7b4b4be" + integrity sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ== case-sensitive-paths-webpack-plugin@^2.3.0: version "2.4.0" @@ -3184,11 +3250,6 @@ character-reference-invalid@^1.0.0: resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== -charcodes@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/charcodes/-/charcodes-0.2.0.tgz#5208d327e6cc05f99eb80ffc814707572d1f14e4" - integrity sha512-Y4kiDb+AM4Ecy58YkuZrrSRJBDQdQ2L+NyS1vHHFtNtUjgutcZfx3yp1dAONI/oPaPmyGfCLx5CxL+zauIMyKQ== - chokidar@^3.4.2: version "3.5.3" resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -3232,9 +3293,9 @@ clean-css@^4.2.3: source-map "~0.6.0" clean-css@^5.2.2: - version "5.3.0" - resolved "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz#ad3d8238d5f3549e83d5f87205189494bc7cbb59" - integrity sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ== + version "5.3.1" + resolved "https://registry.npmjs.org/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" + integrity sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg== dependencies: source-map "~0.6.0" @@ -3434,22 +3495,22 @@ copy-descriptor@^0.1.0: integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== core-js-compat@^3.21.0, core-js-compat@^3.22.1, core-js-compat@^3.8.1: - version "3.23.1" - resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.1.tgz#23d44d9f209086e60dabf9130cea7719af6e199b" - integrity sha512-KeYrEc8t6FJsKYB2qnDwRHWaC0cJNaqlHfCpMe5q3j/W1nje3moib/txNklddLPCtGb+etcBIyJ8zuMa/LN5/A== + version "3.24.1" + resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.24.1.tgz#d1af84a17e18dfdd401ee39da9996f9a7ba887de" + integrity sha512-XhdNAGeRnTpp8xbD+sR/HFDK9CbeeeqXT6TuofXh3urqEevzkWmLRgrVoykodsw8okqo2pu1BOmuCKrHx63zdw== dependencies: - browserslist "^4.20.4" + browserslist "^4.21.3" semver "7.0.0" core-js-pure@^3.8.1: - version "3.23.1" - resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.23.1.tgz#0b27e4c3ad46178b84e790dbbb81987218ab82ad" - integrity sha512-3qNgf6TqI3U1uhuSYRzJZGfFd4T+YlbyVPl+jgRiKjdZopvG4keZQwWZDAWpu1UH9nCgTpUzIV3GFawC7cJsqg== + version "3.24.1" + resolved "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.24.1.tgz#8839dde5da545521bf282feb7dc6d0b425f39fd3" + integrity sha512-r1nJk41QLLPyozHUUPmILCEMtMw24NG4oWK6RbsDdjzQgg9ZvrUsPBj1MnG0wXXp1DCDU6j+wUvEmBSrtRbLXg== core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: - version "3.23.1" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.23.1.tgz#9f9a9255115f62c512db56d567f636da32ca0b78" - integrity sha512-wfMYHWi1WQjpgZNC9kAlN4ut04TM9fUTdi7CqIoTVM7yaiOUQTklOzfb+oWH3r9edQcT3F887swuVmxrV+CC8w== + version "3.24.1" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.24.1.tgz#cf7724d41724154010a6576b7b57d94c5d66e64f" + integrity sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg== core-util-is@~1.0.0: version "1.0.3" @@ -3568,11 +3629,6 @@ cssesc@^3.0.0: resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -csstype@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" - integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== - currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -3803,10 +3859,10 @@ ee-first@1.1.1: resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== -electron-to-chromium@^1.4.147: - version "1.4.156" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.156.tgz#fc398e1bfbe586135351ebfaf198473a82923af5" - integrity sha512-/Wj5NC7E0wHaMCdqxWz9B0lv7CcycDTiHyXCtbbu3pXM9TV2AOp8BtMqkVuqvJNdEvltBG6LxT2Q+BxY4LUCIA== +electron-to-chromium@^1.4.202: + version "1.4.210" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz#12611fe874b833a3bf3671438b5893aba7858980" + integrity sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ== element-resize-detector@^1.2.2: version "1.2.4" @@ -3839,10 +3895,10 @@ endent@^2.0.1: fast-json-parse "^1.0.3" objectorarray "^1.0.5" -enhanced-resolve@^5.9.3: - version "5.9.3" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88" - integrity sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow== +enhanced-resolve@^5.10.0: + version "5.10.0" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -4190,9 +4246,9 @@ fault@^1.0.0: format "^0.2.0" fetch-retry@^5.0.2: - version "5.0.2" - resolved "https://registry.npmjs.org/fetch-retry/-/fetch-retry-5.0.2.tgz#4c55663a7c056cb45f182394e479464f0ff8f3e3" - integrity sha512-57Hmu+1kc6pKFUGVIobT7qw3NeAzY/uNN26bSevERLVvf6VGFR/ooDCOFBHMNDgAxBiU2YJq1D0vFzc6U1DcPw== + version "5.0.3" + resolved "https://registry.npmjs.org/fetch-retry/-/fetch-retry-5.0.3.tgz#edfa3641892995f9afee94f25b168827aa97fe3d" + integrity sha512-uJQyMrX5IJZkhoEUBQ3EjxkeiZkppBd5jS/fMTJmfZxLSiaQjv2zD0kTvuvkSH89uFvgSlB6ueGpjD3HWN7Bxw== file-loader@^6.2.0: version "6.2.0" @@ -4298,9 +4354,9 @@ flat-cache@^3.0.4: rimraf "^3.0.2" flatted@^3.1.0: - version "3.2.5" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" - integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== + version "3.2.6" + resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.6.tgz#022e9218c637f9f3fc9c35ab9c9193f05add60b2" + integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== for-in@^1.0.2: version "1.0.2" @@ -4404,7 +4460,7 @@ fs-minipass@^2.0.0: dependencies: minipass "^3.0.0" -fs-monkey@1.0.3, fs-monkey@^1.0.3: +fs-monkey@^1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== @@ -5072,7 +5128,7 @@ is-callable@^1.1.4, is-callable@^1.2.4: resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== -is-core-module@^2.8.1: +is-core-module@^2.9.0: version "2.9.0" resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== @@ -5371,9 +5427,9 @@ istanbul-lib-report@^3.0.0: supports-color "^7.1.0" istanbul-reports@^3.1.4: - version "3.1.4" - resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" - integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== + version "3.1.5" + resolved "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" + integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -5731,14 +5787,7 @@ mem@^8.1.1: map-age-cleaner "^0.1.3" mimic-fn "^3.1.0" -memfs@^3.1.2: - version "3.4.4" - resolved "https://registry.npmjs.org/memfs/-/memfs-3.4.4.tgz#e8973cd8060548916adcca58a248e7805c715e89" - integrity sha512-W4gHNUE++1oSJVn8Y68jPXi+mkx3fXR5ITE/Ubz6EQ3xRpCN5k2CQ4AUR8094Z7211F876TyoBACGsIveqgiGA== - dependencies: - fs-monkey "1.0.3" - -memfs@^3.2.2: +memfs@^3.1.2, memfs@^3.2.2: version "3.4.7" resolved "https://registry.npmjs.org/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== @@ -5906,9 +5955,9 @@ minipass-pipeline@^1.2.2: minipass "^3.0.0" minipass@^3.0.0, minipass@^3.1.1: - version "3.1.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" - integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== + version "3.3.4" + resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz#ca99f95dd77c43c7a76bf51e6d200025eee0ffae" + integrity sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw== dependencies: yallist "^4.0.0" @@ -6028,10 +6077,10 @@ node-fetch@^2.6.1, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" -node-releases@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz#280ed5bc3eba0d96ce44897d8aee478bfb3d9666" - integrity sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q== +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: version "2.5.0" @@ -6796,9 +6845,9 @@ qs@6.10.3: side-channel "^1.0.4" qs@^6.10.0: - version "6.10.5" - resolved "https://registry.npmjs.org/qs/-/qs-6.10.5.tgz#974715920a80ff6a262264acd2c7e6c2a53282b4" - integrity sha512-O5RlPh0VFtR78y79rgcgKK4wbAI0C5zGVLztOIdpWX6ep368q5Hv6XRxDvXuZ9q3C6v+e3n8UfZZJw7IIG27eQ== + version "6.11.0" + resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== dependencies: side-channel "^1.0.4" @@ -6853,9 +6902,9 @@ react-docgen-typescript@^2.1.1: integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg== react-docgen@^5.0.0: - version "5.4.2" - resolved "https://registry.npmjs.org/react-docgen/-/react-docgen-5.4.2.tgz#697ec899e8dd493bb7ba0d50ec0aa5e49f41d3fa" - integrity sha512-4Z5XYpHsn2bbUfaflxoS30VhUvQLBe4GCwwM5v1e1FUOeDdaoJi6wUGSmYp6OdXYEISEAOEIaSPBk4iezNCKBw== + version "5.4.3" + resolved "https://registry.npmjs.org/react-docgen/-/react-docgen-5.4.3.tgz#7d297f73b977d0c7611402e5fc2a168acf332b26" + integrity sha512-xlLJyOlnfr8lLEEeaDZ+X2J/KJoe6Nr9AzxnkdQWush5hz2ZSu66w6iLMOScMmxoSHWpWMn+k3v5ZiyCfcWsOA== dependencies: "@babel/core" "^7.7.5" "@babel/generator" "^7.12.11" @@ -7081,10 +7130,10 @@ regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: define-properties "^1.1.3" functions-have-names "^1.2.2" -regexpu-core@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" - integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== +regexpu-core@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d" + integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA== dependencies: regenerate "^1.4.2" regenerate-unicode-properties "^10.0.1" @@ -7218,11 +7267,11 @@ resolve-url@^0.2.1: integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.3.2: - version "1.22.0" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" - integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + version "1.22.1" + resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== dependencies: - is-core-module "^2.8.1" + is-core-module "^2.9.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -7614,9 +7663,9 @@ statuses@2.0.1: integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== store2@^2.12.0: - version "2.13.2" - resolved "https://registry.npmjs.org/store2/-/store2-2.13.2.tgz#01ad8802ca5b445b9c316b55e72645c13a3cd7e3" - integrity sha512-CMtO2Uneg3SAz/d6fZ/6qbqqQHi2ynq6/KzMD/26gTkiEShCcpqFfTHgOxsE0egAq6SX3FmN4CeSqn8BzXQkJg== + version "2.14.2" + resolved "https://registry.npmjs.org/store2/-/store2-2.14.2.tgz#56138d200f9fe5f582ad63bc2704dbc0e4a45068" + integrity sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w== storybook-dark-mode@^1.1.0: version "1.1.0" @@ -7763,9 +7812,9 @@ style-to-object@0.3.0, style-to-object@^0.3.0: inline-style-parser "0.1.1" sucrase@^3.21.0: - version "3.24.0" - resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.24.0.tgz#66a8f2cc845bc441706ce5f3056de283289067b6" - integrity sha512-SevqflhW356TKEyWjFHg2e5f3eH+5rzmsMJxrVMDvZIEHh/goYrpzDGA6APEj4ME9MdGm8oNgIzi1eF3c3dDQA== + version "3.25.0" + resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.25.0.tgz#6dffa34e614b3347877507a4380cc4f022b7b7aa" + integrity sha512-WxTtwEYXSmZArPGStGBicyRsg5TBEFhT5b7N+tF+zauImP0Acy+CoUK0/byJ8JNPK/5lbpWIVuFagI4+0l85QQ== dependencies: commander "^4.0.0" glob "7.1.6" @@ -7878,18 +7927,18 @@ terser-webpack-plugin@^5.0.3, terser-webpack-plugin@^5.1.3: terser "^5.7.2" terser@^4.6.3: - version "4.8.0" - resolved "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" - integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== + version "4.8.1" + resolved "https://registry.npmjs.org/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" + integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== dependencies: commander "^2.20.0" source-map "~0.6.1" source-map-support "~0.5.12" terser@^5.10.0, terser@^5.3.4, terser@^5.7.2: - version "5.14.1" - resolved "https://registry.npmjs.org/terser/-/terser-5.14.1.tgz#7c95eec36436cb11cf1902cc79ac564741d19eca" - integrity sha512-+ahUAE+iheqBTDxXhTisdA8hgvbEG1hHOQ9xmNjeUJSoi6DU/gMrKNcfZjHkyY6Alnuyc+ikYJaxxfHkT3+WuQ== + version "5.14.2" + resolved "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" @@ -8042,9 +8091,9 @@ type-is@~1.6.18: mime-types "~2.1.24" uglify-js@^3.1.4: - version "3.16.0" - resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.0.tgz#b778ba0831ca102c1d8ecbdec2d2bdfcc7353190" - integrity sha512-FEikl6bR30n0T3amyBh3LoiBdqHRy/f4H80+My34HOesOKyHfOsxAPAxOoqC0JUnC1amnO0IwkYC3sko51caSw== + version "3.16.3" + resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.16.3.tgz#94c7a63337ee31227a18d03b8a3041c210fd1f1d" + integrity sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw== unbox-primitive@^1.0.2: version "1.0.2" @@ -8211,6 +8260,14 @@ untildify@^2.0.0: dependencies: os-homedir "^1.0.0" +update-browserslist-db@^1.0.5: + version "1.0.5" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -8271,11 +8328,11 @@ uuid@^3.3.2: integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== v8-to-istanbul@^9.0.0: - version "9.0.0" - resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz#be0dae58719fc53cb97e5c7ac1d7e6d4f5b19511" - integrity sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw== + version "9.0.1" + resolved "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" + integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== dependencies: - "@jridgewell/trace-mapping" "^0.3.7" + "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" @@ -8315,7 +8372,7 @@ vfile@^4.0.0: unist-util-stringify-position "^2.0.0" vfile-message "^2.0.0" -watchpack@^2.2.0, watchpack@^2.3.1: +watchpack@^2.2.0, watchpack@^2.4.0: version "2.4.0" resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== @@ -8405,20 +8462,20 @@ webpack-virtual-modules@^0.4.1: integrity sha512-h9atBP/bsZohWpHnr+2sic8Iecb60GxftXsWNLLLSqewgIsGzByd2gcIID4nXcG+3tNe4GQG3dLcff3kXupdRA== webpack@4, "webpack@>=4.43.0 <6.0.0", webpack@^5.73.0, webpack@^5.9.0: - version "5.73.0" - resolved "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz#bbd17738f8a53ee5760ea2f59dce7f3431d35d38" - integrity sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA== + version "5.74.0" + resolved "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" + integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" + acorn "^8.7.1" acorn-import-assertions "^1.7.6" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.9.3" + enhanced-resolve "^5.10.0" es-module-lexer "^0.9.0" eslint-scope "5.1.1" events "^3.2.0" @@ -8431,7 +8488,7 @@ webpack@4, "webpack@>=4.43.0 <6.0.0", webpack@^5.73.0, webpack@^5.9.0: schema-utils "^3.1.0" tapable "^2.1.1" terser-webpack-plugin "^5.1.3" - watchpack "^2.3.1" + watchpack "^2.4.0" webpack-sources "^3.2.3" whatwg-url@^5.0.0: @@ -8506,9 +8563,9 @@ wrappy@1: integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== ws@^8.2.3: - version "8.8.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769" - integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ== + version "8.8.1" + resolved "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" + integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== x-default-browser@^0.4.0: version "0.4.0" diff --git a/yarn.lock b/yarn.lock index 545c47c4b0..cf7e53ec0b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@adobe/css-tools@^4.0.1": + version "4.0.1" + resolved "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.0.1.tgz#b38b444ad3aa5fedbb15f2f746dcd934226a12dd" + integrity sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g== + "@ampproject/remapping@^2.1.0": version "2.1.2" resolved "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" @@ -41,6 +46,14 @@ ajv-draft-04 "^1.0.0" call-me-maybe "^1.0.1" +"@apollo/explorer@^1.1.1": + version "1.1.1" + resolved "https://registry.npmjs.org/@apollo/explorer/-/explorer-1.1.1.tgz#58f539f01aaab573eb23c206c920cd742c4241e5" + integrity sha512-et9B4057irrakX2TnorKnOoez49db7O+d/t5TwYpdcYWA4eS5US6c0toOAAfSlusAPF3tCNr4uTZWM4Q9RhgrA== + dependencies: + graphql-ws "^5.9.0" + subscriptions-transport-ws "^0.11.0" + "@apollo/protobufjs@1.2.2": version "1.2.2" resolved "https://registry.npmjs.org/@apollo/protobufjs/-/protobufjs-1.2.2.tgz#4bd92cd7701ccaef6d517cdb75af2755f049f87c" @@ -166,6 +179,13 @@ signedsource "^1.0.0" yargs "^15.3.1" +"@ardatan/sync-fetch@0.0.1": + version "0.0.1" + resolved "https://registry.npmjs.org/@ardatan/sync-fetch/-/sync-fetch-0.0.1.tgz#3385d3feedceb60a896518a1db857ec1e945348f" + integrity sha512-xhlTqH0m31mnsG0tIP4ETgfSB6gXDaYYsUWTrlUV93fFQPI9dd8hE0Ot6MHLCtqgB32hwJAC3YZMWlXZw7AleA== + dependencies: + node-fetch "^2.6.1" + "@asyncapi/avro-schema-parser@^0.3.0": version "0.3.0" resolved "https://registry.npmjs.org/@asyncapi/avro-schema-parser/-/avro-schema-parser-0.3.0.tgz#6922acc559ef999c57e81297d78ffe680fc92b3c" @@ -193,10 +213,10 @@ node-fetch "^2.6.0" tiny-merge-patch "^0.1.2" -"@asyncapi/react-component@1.0.0-next.39": - version "1.0.0-next.39" - resolved "https://registry.npmjs.org/@asyncapi/react-component/-/react-component-1.0.0-next.39.tgz#2aa236b1783f36249752b3c30e0c7e0125af8c1f" - integrity sha512-UQYmzbvKwDm3HVGjLL1znK35bOKlWNiTUw29oSe6Xdil/Y7RODLctGQrbwKSCeP0VwtsokhwivQ3QHuL3byjVw== +"@asyncapi/react-component@1.0.0-next.40": + version "1.0.0-next.40" + resolved "https://registry.npmjs.org/@asyncapi/react-component/-/react-component-1.0.0-next.40.tgz#91cb16008f18b6614f00095029f37380a1ad557b" + integrity sha512-C46TXu1agGWEKE6gAdJ+Nf+agdXPeoUUFhpfR03IaCU108kOw05HarHm6VX4y3/nDuNv36p4UmbU4dY6n2t0aA== dependencies: "@asyncapi/avro-schema-parser" "^0.3.0" "@asyncapi/openapi-schema-parser" "^2.0.0" @@ -205,6 +225,7 @@ isomorphic-dompurify "^0.13.0" marked "^4.0.14" openapi-sampler "^1.2.1" + react-icons "^4.4.0" use-resize-observer "^8.0.0" "@asyncapi/specs@^2.14.0": @@ -391,7 +412,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/code-frame@^7.0.0": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.18.6": version "7.18.6" resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== @@ -405,7 +426,7 @@ dependencies: "@babel/highlight" "^7.16.7" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4", "@babel/compat-data@^7.16.8": +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4": version "7.16.8" resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== @@ -415,7 +436,12 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.7.tgz#078d8b833fbbcc95286613be8c716cef2b519fa2" integrity sha512-p8pdE6j0a29TNGebNm7NzYZWB3xVZJBZ7XGs42uAKzQo8VQ3F0By/cQCtUEABwIqw5zo6WA4NbmxsfzADzMKnQ== -"@babel/core@^7.1.0", "@babel/core@^7.13.16", "@babel/core@^7.14.0", "@babel/core@^7.15.5": +"@babel/compat-data@^7.18.8": + version "7.18.8" + resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== + +"@babel/core@^7.1.0", "@babel/core@^7.13.16", "@babel/core@^7.14.0": version "7.16.12" resolved "https://registry.npmjs.org/@babel/core/-/core-7.16.12.tgz#5edc53c1b71e54881315923ae2aedea2522bb784" integrity sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg== @@ -457,6 +483,27 @@ json5 "^2.1.2" semver "^6.3.0" +"@babel/core@^7.18.5": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59" + integrity sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.9" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + "@babel/generator@^7.14.0", "@babel/generator@^7.16.8", "@babel/generator@^7.7.2": version "7.16.8" resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" @@ -475,6 +522,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/generator/-/generator-7.18.9.tgz#68337e9ea8044d6ddc690fb29acae39359cca0a5" + integrity sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug== + dependencies: + "@babel/types" "^7.18.9" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + "@babel/helper-annotate-as-pure@^7.16.0", "@babel/helper-annotate-as-pure@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" @@ -482,13 +538,20 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" - integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== dependencies: - "@babel/helper-explode-assignable-expression" "^7.16.7" - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" + integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.18.6" + "@babel/types" "^7.18.9" "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.16.7": version "7.16.7" @@ -510,7 +573,17 @@ browserslist "^4.17.5" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7": +"@babel/helper-compilation-targets@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" + integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.20.2" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.16.7": version "7.16.10" resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz#8a6959b9cc818a88815ba3c5474619e9c0f2c21c" integrity sha512-wDeej0pu3WN/ffTxMNCPW5UCiOav8IcLRxSIyp/9+IF2xJUM9h/OYjg0IJLHaL6F8oU8kqMz9nc1vryXhMsgXg== @@ -523,6 +596,19 @@ "@babel/helper-replace-supers" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" +"@babel/helper-create-class-features-plugin@^7.18.6": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz#d802ee16a64a9e824fcbf0a2ffc92f19d58550ce" + integrity sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-create-regexp-features-plugin@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz#0cb82b9bac358eb73bfbd73985a776bfa6b14d48" @@ -531,6 +617,14 @@ "@babel/helper-annotate-as-pure" "^7.16.7" regexpu-core "^4.7.1" +"@babel/helper-create-regexp-features-plugin@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz#3e35f4e04acbbf25f1b3534a657610a000543d3c" + integrity sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.1.0" + "@babel/helper-define-polyfill-provider@^0.3.1": version "0.3.1" resolved "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" @@ -552,12 +646,17 @@ dependencies: "@babel/types" "^7.16.7" -"@babel/helper-explode-assignable-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" - integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== +"@babel/helper-environment-visitor@^7.18.6", "@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + +"@babel/helper-explode-assignable-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" + integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== dependencies: - "@babel/types" "^7.16.7" + "@babel/types" "^7.18.6" "@babel/helper-function-name@^7.16.7": version "7.16.7" @@ -568,6 +667,14 @@ "@babel/template" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" + integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== + dependencies: + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.9" + "@babel/helper-get-function-arity@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" @@ -582,6 +689,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-member-expression-to-functions@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" @@ -589,6 +703,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-member-expression-to-functions@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" + integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== + dependencies: + "@babel/types" "^7.18.9" + "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.0", "@babel/helper-module-imports@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" @@ -596,6 +717,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-module-transforms@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" @@ -624,6 +752,20 @@ "@babel/traverse" "^7.17.3" "@babel/types" "^7.17.0" +"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" + integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + "@babel/helper-optimise-call-expression@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" @@ -631,19 +773,32 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-optimise-call-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" + integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== -"@babel/helper-remap-async-to-generator@^7.16.8": - version "7.16.8" - resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" - integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== +"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f" + integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w== + +"@babel/helper-remap-async-to-generator@^7.18.6": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" + integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-wrap-function" "^7.16.8" - "@babel/types" "^7.16.8" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-wrap-function" "^7.18.9" + "@babel/types" "^7.18.9" "@babel/helper-replace-supers@^7.16.7": version "7.16.7" @@ -656,6 +811,17 @@ "@babel/traverse" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6" + integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + "@babel/helper-simple-access@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" @@ -670,6 +836,13 @@ dependencies: "@babel/types" "^7.17.0" +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-skip-transparent-expression-wrappers@^7.16.0": version "7.16.0" resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" @@ -677,6 +850,13 @@ dependencies: "@babel/types" "^7.16.0" +"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" + integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== + dependencies: + "@babel/types" "^7.18.9" + "@babel/helper-split-export-declaration@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" @@ -684,6 +864,13 @@ dependencies: "@babel/types" "^7.16.7" +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-validator-identifier@^7.16.7", "@babel/helper-validator-identifier@^7.18.6": version "7.18.6" resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" @@ -694,15 +881,20 @@ resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== -"@babel/helper-wrap-function@^7.16.8": - version "7.16.8" - resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" - integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helper-wrap-function@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.9.tgz#ae1feddc6ebbaa2fd79346b77821c3bd73a39646" + integrity sha512-cG2ru3TRAL6a60tfQflpEfs4ldiPwF6YW3zfJiRgmoFVIaC1vGnBBgatfec+ZUziPHkHSaXAuEck3Cdkf3eRpQ== dependencies: - "@babel/helper-function-name" "^7.16.7" - "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.8" - "@babel/types" "^7.16.8" + "@babel/helper-function-name" "^7.18.9" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" "@babel/helpers@^7.16.7": version "7.16.7" @@ -722,6 +914,15 @@ "@babel/traverse" "^7.17.3" "@babel/types" "^7.17.0" +"@babel/helpers@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" + integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== + dependencies: + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + "@babel/highlight@^7.0.0": version "7.16.10" resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" @@ -745,32 +946,38 @@ resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.17.9.tgz#9c94189a6062f0291418ca021077983058e171ef" integrity sha512-vqUSBLP8dQHFPdPi9bc5GK9vRkYHJ49fsZdtoJ8EQ8ibpwk5rPKfvNIwChB0KVXcIjcepEBBd2VHC5r9Gy8ueg== -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050" - integrity sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg== - dependencies: - "@babel/helper-plugin-utils" "^7.16.7" +"@babel/parser@^7.18.6", "@babel/parser@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" + integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9" - integrity sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" + integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" - "@babel/plugin-proposal-optional-chaining" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-async-generator-functions@^7.16.8": - version "7.16.8" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" - integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" + integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" + +"@babel/plugin-proposal-async-generator-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz#aedac81e6fc12bb643374656dd5f2605bf743d17" + integrity sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w== + dependencies: + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.16.7": +"@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.13.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== @@ -778,48 +985,56 @@ "@babel/helper-create-class-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-proposal-class-static-block@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.16.7.tgz#712357570b612106ef5426d13dc433ce0f200c2a" - integrity sha512-dgqJJrcZoG/4CkMopzhPJjGxsIe9A8RlkQLnL/Vhhx8AA9ZuaRwGSlscSh42hazc7WSrya/IK7mTeoF0DP9tEw== +"@babel/plugin-proposal-class-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-class-static-block@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" + integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-proposal-dynamic-import@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" - integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== +"@babel/plugin-proposal-dynamic-import@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" + integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-proposal-export-namespace-from@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" - integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== +"@babel/plugin-proposal-export-namespace-from@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" + integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" - integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ== +"@babel/plugin-proposal-json-strings@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" + integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" - integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== +"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" + integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== @@ -827,15 +1042,23 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" - integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" + integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.16.7": +"@babel/plugin-proposal-object-rest-spread@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz#94593ef1ddf37021a25bdcb5754c4a8d534b01d8" integrity sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA== @@ -846,15 +1069,26 @@ "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.16.7" -"@babel/plugin-proposal-optional-catch-binding@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" - integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== +"@babel/plugin-proposal-object-rest-spread@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" + integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/compat-data" "^7.18.8" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.18.8" + +"@babel/plugin-proposal-optional-catch-binding@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" + integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.16.7": +"@babel/plugin-proposal-optional-chaining@^7.13.12": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== @@ -863,25 +1097,42 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.16.11": - version "7.16.11" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" - integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== +"@babel/plugin-proposal-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" + integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== dependencies: - "@babel/helper-create-class-features-plugin" "^7.16.10" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-property-in-object@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce" - integrity sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ== +"@babel/plugin-proposal-private-methods@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" + integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-create-class-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-private-property-in-object@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503" + integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.16.7", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": +"@babel/plugin-proposal-unicode-property-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" + integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== @@ -938,6 +1189,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-syntax-import-assertions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4" + integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-import-meta@^7.8.3": version "7.10.4" resolved "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" @@ -959,6 +1217,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" +"@babel/plugin-syntax-jsx@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": version "7.10.4" resolved "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" @@ -1022,37 +1287,65 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-arrow-functions@^7.0.0", "@babel/plugin-transform-arrow-functions@^7.16.7": +"@babel/plugin-syntax-typescript@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" + integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-arrow-functions@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-async-to-generator@^7.16.8": - version "7.16.8" - resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" - integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== +"@babel/plugin-transform-arrow-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" + integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-remap-async-to-generator" "^7.16.8" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-block-scoped-functions@^7.0.0", "@babel/plugin-transform-block-scoped-functions@^7.16.7": +"@babel/plugin-transform-async-to-generator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" + integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== + dependencies: + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" + +"@babel/plugin-transform-block-scoped-functions@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-block-scoping@^7.0.0", "@babel/plugin-transform-block-scoping@^7.16.7": +"@babel/plugin-transform-block-scoped-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" + integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-block-scoping@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-classes@^7.0.0", "@babel/plugin-transform-classes@^7.16.7": +"@babel/plugin-transform-block-scoping@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" + integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-classes@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ== @@ -1066,21 +1359,57 @@ "@babel/helper-split-export-declaration" "^7.16.7" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.0.0", "@babel/plugin-transform-computed-properties@^7.16.7": +"@babel/plugin-transform-classes@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz#90818efc5b9746879b869d5ce83eb2aa48bbc3da" + integrity sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-destructuring@^7.0.0", "@babel/plugin-transform-destructuring@^7.16.7": +"@babel/plugin-transform-computed-properties@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" + integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-destructuring@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz#ca9588ae2d63978a4c29d3f33282d8603f618e23" integrity sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-dotall-regex@^7.16.7", "@babel/plugin-transform-dotall-regex@^7.4.4": +"@babel/plugin-transform-destructuring@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.9.tgz#68906549c021cb231bee1db21d3b5b095f8ee292" + integrity sha512-p5VCYNddPLkZTq4XymQIaIfZNJwT9YsjkPOhkVEqt6QIpQFZVM9IltqqYpOEkJoN1DPznmxUDyZ5CTZs/ZCuHA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-dotall-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" + integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-dotall-regex@^7.4.4": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== @@ -1088,20 +1417,20 @@ "@babel/helper-create-regexp-features-plugin" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-duplicate-keys@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" - integrity sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw== +"@babel/plugin-transform-duplicate-keys@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" + integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-exponentiation-operator@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" - integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== +"@babel/plugin-transform-exponentiation-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" + integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.16.7": version "7.16.7" @@ -1111,14 +1440,21 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-flow" "^7.16.7" -"@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.16.7": +"@babel/plugin-transform-for-of@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-function-name@^7.0.0", "@babel/plugin-transform-function-name@^7.16.7": +"@babel/plugin-transform-for-of@^7.18.8": + version "7.18.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" + integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-function-name@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== @@ -1127,30 +1463,53 @@ "@babel/helper-function-name" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-literals@^7.0.0", "@babel/plugin-transform-literals@^7.16.7": +"@babel/plugin-transform-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" + integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== + dependencies: + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-literals@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-member-expression-literals@^7.0.0", "@babel/plugin-transform-member-expression-literals@^7.16.7": +"@babel/plugin-transform-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" + integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-member-expression-literals@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-modules-amd@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" - integrity sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g== +"@babel/plugin-transform-member-expression-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" + integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== dependencies: - "@babel/helper-module-transforms" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-modules-amd@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21" + integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== + dependencies: + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.16.8": +"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.13.8": version "7.16.8" resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe" integrity sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA== @@ -1160,40 +1519,51 @@ "@babel/helper-simple-access" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7" - integrity sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw== +"@babel/plugin-transform-modules-commonjs@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" + integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== dependencies: - "@babel/helper-hoist-variables" "^7.16.7" - "@babel/helper-module-transforms" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-validator-identifier" "^7.16.7" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" - integrity sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ== +"@babel/plugin-transform-modules-systemjs@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz#545df284a7ac6a05125e3e405e536c5853099a06" + integrity sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A== dependencies: - "@babel/helper-module-transforms" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-validator-identifier" "^7.18.6" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-named-capturing-groups-regex@^7.16.8": - version "7.16.8" - resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252" - integrity sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw== +"@babel/plugin-transform-modules-umd@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" + integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-new-target@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" - integrity sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz#c89bfbc7cc6805d692f3a49bc5fc1b630007246d" + integrity sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.16.7": +"@babel/plugin-transform-new-target@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" + integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-object-super@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== @@ -1201,6 +1571,14 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-replace-supers" "^7.16.7" +"@babel/plugin-transform-object-super@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" + integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" + "@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.16.7": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" @@ -1208,35 +1586,56 @@ dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-property-literals@^7.0.0", "@babel/plugin-transform-property-literals@^7.16.7": +"@babel/plugin-transform-parameters@^7.18.8": + version "7.18.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" + integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-property-literals@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-react-constant-elements@^7.14.5": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.16.7.tgz#19e9e4c2df2f6c3e6b3aea11778297d81db8df62" - integrity sha512-lF+cfsyTgwWkcw715J88JhMYJ5GpysYNLhLP1PkvkhTRN7B3e74R/1KsDxFxhRpSn0UUD3IWM4GvdBR2PEbbQQ== +"@babel/plugin-transform-property-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" + integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-react-display-name@^7.0.0", "@babel/plugin-transform-react-display-name@^7.16.7": +"@babel/plugin-transform-react-constant-elements@^7.17.12": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.18.9.tgz#ff6aeedd38f57ba6b41dcf824fcc8bcedb3e783f" + integrity sha512-IrTYh1I3YCEL1trjknnlLKTp5JggjzhKl/d3ibzPc97JhpFcDTr38Jdek/oX4cFbS6By0bXJcOkpRvJ5ZHK2wQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-react-display-name@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz#7b6d40d232f4c0f550ea348593db3b21e2404340" integrity sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-react-jsx-development@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz#43a00724a3ed2557ed3f276a01a929e6686ac7b8" - integrity sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A== +"@babel/plugin-transform-react-display-name@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" + integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== dependencies: - "@babel/plugin-transform-react-jsx" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-react-jsx@^7.0.0", "@babel/plugin-transform-react-jsx@^7.16.7": +"@babel/plugin-transform-react-jsx-development@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" + integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.18.6" + +"@babel/plugin-transform-react-jsx@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz#86a6a220552afd0e4e1f0388a68a372be7add0d4" integrity sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag== @@ -1247,36 +1646,55 @@ "@babel/plugin-syntax-jsx" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/plugin-transform-react-pure-annotations@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.7.tgz#232bfd2f12eb551d6d7d01d13fe3f86b45eb9c67" - integrity sha512-hs71ToC97k3QWxswh2ElzMFABXHvGiJ01IB1TbYQDGeWRKWz/MPUTh5jGExdHvosYKpnJW5Pm3S4+TA3FyX+GA== +"@babel/plugin-transform-react-jsx@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.18.6.tgz#2721e96d31df96e3b7ad48ff446995d26bc028ff" + integrity sha512-Mz7xMPxoy9kPS/JScj6fJs03TZ/fZ1dJPlMjRAgTaxaS0fUBk8FV/A2rRgfPsVCZqALNwMexD+0Uaf5zlcKPpw== dependencies: - "@babel/helper-annotate-as-pure" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-jsx" "^7.18.6" + "@babel/types" "^7.18.6" -"@babel/plugin-transform-regenerator@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb" - integrity sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q== +"@babel/plugin-transform-react-pure-annotations@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz#561af267f19f3e5d59291f9950fd7b9663d0d844" + integrity sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ== dependencies: - regenerator-transform "^0.14.2" + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-reserved-words@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" - integrity sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg== +"@babel/plugin-transform-regenerator@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73" + integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" + regenerator-transform "^0.15.0" -"@babel/plugin-transform-shorthand-properties@^7.0.0", "@babel/plugin-transform-shorthand-properties@^7.16.7": +"@babel/plugin-transform-reserved-words@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" + integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-shorthand-properties@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-spread@^7.0.0", "@babel/plugin-transform-spread@^7.16.7": +"@babel/plugin-transform-shorthand-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" + integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-spread@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg== @@ -1284,26 +1702,41 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" -"@babel/plugin-transform-sticky-regex@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" - integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== +"@babel/plugin-transform-spread@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz#6ea7a6297740f381c540ac56caf75b05b74fb664" + integrity sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" -"@babel/plugin-transform-template-literals@^7.0.0", "@babel/plugin-transform-template-literals@^7.16.7": +"@babel/plugin-transform-sticky-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" + integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-template-literals@^7.0.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA== dependencies: "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-typeof-symbol@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" - integrity sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ== +"@babel/plugin-transform-template-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" + integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-typeof-symbol@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" + integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" "@babel/plugin-transform-typescript@^7.16.7": version "7.16.8" @@ -1314,52 +1747,62 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-typescript" "^7.16.7" -"@babel/plugin-transform-unicode-escapes@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" - integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q== +"@babel/plugin-transform-typescript@^7.18.6": + version "7.18.8" + resolved "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.8.tgz#303feb7a920e650f2213ef37b36bbf327e6fa5a0" + integrity sha512-p2xM8HI83UObjsZGofMV/EdYjamsDm6MoN3hXPYIT0+gxIoopE+B7rPYKAxfrz9K9PK7JafTTjqYC6qipLExYA== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-typescript" "^7.18.6" -"@babel/plugin-transform-unicode-regex@^7.16.7": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" - integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== +"@babel/plugin-transform-unicode-escapes@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz#0d01fb7fb2243ae1c033f65f6e3b4be78db75f27" + integrity sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/preset-env@^7.15.6": - version "7.16.11" - resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.16.11.tgz#5dd88fd885fae36f88fd7c8342475c9f0abe2982" - integrity sha512-qcmWG8R7ZW6WBRPZK//y+E3Cli151B20W1Rv7ln27vuPaXU/8TKms6jFdiJtF7UDTxcrb7mZd88tAeK9LjdT8g== +"@babel/plugin-transform-unicode-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" + integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== dependencies: - "@babel/compat-data" "^7.16.8" - "@babel/helper-compilation-targets" "^7.16.7" - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.7" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.7" - "@babel/plugin-proposal-async-generator-functions" "^7.16.8" - "@babel/plugin-proposal-class-properties" "^7.16.7" - "@babel/plugin-proposal-class-static-block" "^7.16.7" - "@babel/plugin-proposal-dynamic-import" "^7.16.7" - "@babel/plugin-proposal-export-namespace-from" "^7.16.7" - "@babel/plugin-proposal-json-strings" "^7.16.7" - "@babel/plugin-proposal-logical-assignment-operators" "^7.16.7" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.7" - "@babel/plugin-proposal-numeric-separator" "^7.16.7" - "@babel/plugin-proposal-object-rest-spread" "^7.16.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.16.7" - "@babel/plugin-proposal-optional-chaining" "^7.16.7" - "@babel/plugin-proposal-private-methods" "^7.16.11" - "@babel/plugin-proposal-private-property-in-object" "^7.16.7" - "@babel/plugin-proposal-unicode-property-regex" "^7.16.7" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/preset-env@^7.18.2": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.9.tgz#9b3425140d724fbe590322017466580844c7eaff" + integrity sha512-75pt/q95cMIHWssYtyfjVlvI+QEZQThQbKvR9xH+F/Agtw/s4Wfc2V9Bwd/P39VtixB7oWxGdH4GteTTwYJWMg== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-async-generator-functions" "^7.18.6" + "@babel/plugin-proposal-class-properties" "^7.18.6" + "@babel/plugin-proposal-class-static-block" "^7.18.6" + "@babel/plugin-proposal-dynamic-import" "^7.18.6" + "@babel/plugin-proposal-export-namespace-from" "^7.18.9" + "@babel/plugin-proposal-json-strings" "^7.18.6" + "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" + "@babel/plugin-proposal-numeric-separator" "^7.18.6" + "@babel/plugin-proposal-object-rest-spread" "^7.18.9" + "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-private-methods" "^7.18.6" + "@babel/plugin-proposal-private-property-in-object" "^7.18.6" + "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.18.6" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" @@ -1369,44 +1812,44 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.16.7" - "@babel/plugin-transform-async-to-generator" "^7.16.8" - "@babel/plugin-transform-block-scoped-functions" "^7.16.7" - "@babel/plugin-transform-block-scoping" "^7.16.7" - "@babel/plugin-transform-classes" "^7.16.7" - "@babel/plugin-transform-computed-properties" "^7.16.7" - "@babel/plugin-transform-destructuring" "^7.16.7" - "@babel/plugin-transform-dotall-regex" "^7.16.7" - "@babel/plugin-transform-duplicate-keys" "^7.16.7" - "@babel/plugin-transform-exponentiation-operator" "^7.16.7" - "@babel/plugin-transform-for-of" "^7.16.7" - "@babel/plugin-transform-function-name" "^7.16.7" - "@babel/plugin-transform-literals" "^7.16.7" - "@babel/plugin-transform-member-expression-literals" "^7.16.7" - "@babel/plugin-transform-modules-amd" "^7.16.7" - "@babel/plugin-transform-modules-commonjs" "^7.16.8" - "@babel/plugin-transform-modules-systemjs" "^7.16.7" - "@babel/plugin-transform-modules-umd" "^7.16.7" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.8" - "@babel/plugin-transform-new-target" "^7.16.7" - "@babel/plugin-transform-object-super" "^7.16.7" - "@babel/plugin-transform-parameters" "^7.16.7" - "@babel/plugin-transform-property-literals" "^7.16.7" - "@babel/plugin-transform-regenerator" "^7.16.7" - "@babel/plugin-transform-reserved-words" "^7.16.7" - "@babel/plugin-transform-shorthand-properties" "^7.16.7" - "@babel/plugin-transform-spread" "^7.16.7" - "@babel/plugin-transform-sticky-regex" "^7.16.7" - "@babel/plugin-transform-template-literals" "^7.16.7" - "@babel/plugin-transform-typeof-symbol" "^7.16.7" - "@babel/plugin-transform-unicode-escapes" "^7.16.7" - "@babel/plugin-transform-unicode-regex" "^7.16.7" + "@babel/plugin-transform-arrow-functions" "^7.18.6" + "@babel/plugin-transform-async-to-generator" "^7.18.6" + "@babel/plugin-transform-block-scoped-functions" "^7.18.6" + "@babel/plugin-transform-block-scoping" "^7.18.9" + "@babel/plugin-transform-classes" "^7.18.9" + "@babel/plugin-transform-computed-properties" "^7.18.9" + "@babel/plugin-transform-destructuring" "^7.18.9" + "@babel/plugin-transform-dotall-regex" "^7.18.6" + "@babel/plugin-transform-duplicate-keys" "^7.18.9" + "@babel/plugin-transform-exponentiation-operator" "^7.18.6" + "@babel/plugin-transform-for-of" "^7.18.8" + "@babel/plugin-transform-function-name" "^7.18.9" + "@babel/plugin-transform-literals" "^7.18.9" + "@babel/plugin-transform-member-expression-literals" "^7.18.6" + "@babel/plugin-transform-modules-amd" "^7.18.6" + "@babel/plugin-transform-modules-commonjs" "^7.18.6" + "@babel/plugin-transform-modules-systemjs" "^7.18.9" + "@babel/plugin-transform-modules-umd" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.18.6" + "@babel/plugin-transform-new-target" "^7.18.6" + "@babel/plugin-transform-object-super" "^7.18.6" + "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-property-literals" "^7.18.6" + "@babel/plugin-transform-regenerator" "^7.18.6" + "@babel/plugin-transform-reserved-words" "^7.18.6" + "@babel/plugin-transform-shorthand-properties" "^7.18.6" + "@babel/plugin-transform-spread" "^7.18.9" + "@babel/plugin-transform-sticky-regex" "^7.18.6" + "@babel/plugin-transform-template-literals" "^7.18.9" + "@babel/plugin-transform-typeof-symbol" "^7.18.9" + "@babel/plugin-transform-unicode-escapes" "^7.18.6" + "@babel/plugin-transform-unicode-regex" "^7.18.6" "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.16.8" - babel-plugin-polyfill-corejs2 "^0.3.0" - babel-plugin-polyfill-corejs3 "^0.5.0" - babel-plugin-polyfill-regenerator "^0.3.0" - core-js-compat "^3.20.2" + "@babel/types" "^7.18.9" + babel-plugin-polyfill-corejs2 "^0.3.1" + babel-plugin-polyfill-corejs3 "^0.5.2" + babel-plugin-polyfill-regenerator "^0.3.1" + core-js-compat "^3.22.1" semver "^6.3.0" "@babel/preset-flow@^7.13.13": @@ -1429,19 +1872,19 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@^7.14.5": - version "7.16.7" - resolved "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.16.7.tgz#4c18150491edc69c183ff818f9f2aecbe5d93852" - integrity sha512-fWpyI8UM/HE6DfPBzD8LnhQ/OcH8AgTaqcqP2nGOXEUV+VKBR5JRN9hCk9ai+zQQ57vtm9oWeXguBCPNUjytgA== +"@babel/preset-react@^7.17.12": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" + integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== dependencies: - "@babel/helper-plugin-utils" "^7.16.7" - "@babel/helper-validator-option" "^7.16.7" - "@babel/plugin-transform-react-display-name" "^7.16.7" - "@babel/plugin-transform-react-jsx" "^7.16.7" - "@babel/plugin-transform-react-jsx-development" "^7.16.7" - "@babel/plugin-transform-react-pure-annotations" "^7.16.7" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-react-display-name" "^7.18.6" + "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/plugin-transform-react-jsx-development" "^7.18.6" + "@babel/plugin-transform-react-pure-annotations" "^7.18.6" -"@babel/preset-typescript@^7.13.0", "@babel/preset-typescript@^7.15.0", "@babel/preset-typescript@^7.16.0": +"@babel/preset-typescript@^7.13.0": version "7.16.7" resolved "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.16.7.tgz#ab114d68bb2020afc069cd51b37ff98a046a70b9" integrity sha512-WbVEmgXdIyvzB77AQjGBEyYPZx+8tTsO50XtfozQrkW8QB2rLJpH2lgx0TRw5EJrBxOZQ+wCcyPVQvS8tjEHpQ== @@ -1450,6 +1893,15 @@ "@babel/helper-validator-option" "^7.16.7" "@babel/plugin-transform-typescript" "^7.16.7" +"@babel/preset-typescript@^7.17.12": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" + integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-typescript" "^7.18.6" + "@babel/register@^7.13.16": version "7.16.9" resolved "https://registry.npmjs.org/@babel/register/-/register-7.16.9.tgz#fcfb23cfdd9ad95c9771e58183de83b513857806" @@ -1461,7 +1913,7 @@ pirates "^4.0.0" source-map-support "^0.5.16" -"@babel/runtime-corejs3@^7.10.2", "@babel/runtime-corejs3@^7.11.2", "@babel/runtime-corejs3@^7.16.8": +"@babel/runtime-corejs3@^7.10.2", "@babel/runtime-corejs3@^7.11.2": version "7.17.2" resolved "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.2.tgz#fdca2cd05fba63388babe85d349b6801b008fd13" integrity sha512-NcKtr2epxfIrNM4VOmPKO46TvDMCBhgi2CrSHaEarrz+Plk2K5r9QemmOFTGpZaoKnWoGH5MO+CzeRsih/Fcgg== @@ -1469,6 +1921,14 @@ core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" +"@babel/runtime-corejs3@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.18.9.tgz#7bacecd1cb2dd694eacd32a91fcf7021c20770ae" + integrity sha512-qZEWeccZCrHA2Au4/X05QW5CMdm4VjUDCrGq5gf1ZDcM4hRqreKrtwAn7yci9zfgAS9apvnsFXiGBHBAxZdK9A== + dependencies: + core-js-pure "^3.20.2" + regenerator-runtime "^0.13.4" + "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.15.4", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.6.2", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.17.7" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.7.tgz#a5f3328dc41ff39d803f311cfe17703418cf9825" @@ -1476,7 +1936,14 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.10.4", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.6": +"@babel/runtime@^7.10.4", "@babel/runtime@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.18.6": version "7.18.6" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.6.tgz#6a1ef59f838debd670421f8c7f2cbb8da9751580" integrity sha512-t9wi7/AW6XtKahAe20Yw0/mMljKq0B1r2fPdvaAdV/KPDZewFXdaaa6K7lxmZBZ8FBNpCiAT6iHPmd6QO9bKfQ== @@ -1492,6 +1959,15 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" +"@babel/template@^7.18.6": + version "7.18.6" + resolved "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" + integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/types" "^7.18.6" + "@babel/traverse@^7.13.0", "@babel/traverse@^7.14.0", "@babel/traverse@^7.16.10", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.4.5", "@babel/traverse@^7.7.2": version "7.16.10" resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f" @@ -1524,7 +2000,23 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.15.6", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/traverse@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.9.tgz#deeff3e8f1bad9786874cb2feda7a2d77a904f98" + integrity sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.9" + "@babel/types" "^7.18.9" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.16.8" resolved "https://registry.npmjs.org/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== @@ -1540,43 +2032,29 @@ "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" -"@backstage/catalog-client@^1.0.3": - version "1.0.3" - resolved "https://registry.npmjs.org/@backstage/catalog-client/-/catalog-client-1.0.3.tgz#cb91472ccc31df322f69e7e4e80939b3535660cd" - integrity sha512-35Es9jFB9jOZTEtEeCyZHES0bcQkfX4qbmY1GuC6e6ZtO120w+595kmKxc744d7X2WXUIWvhRubqc9/w5blKbg== +"@babel/types@^7.18.4", "@babel/types@^7.18.6", "@babel/types@^7.18.9": + version "7.18.9" + resolved "https://registry.npmjs.org/@babel/types/-/types-7.18.9.tgz#7148d64ba133d8d73a41b3172ac4b83a1452205f" + integrity sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg== dependencies: - "@backstage/catalog-model" "^1.0.3" - "@backstage/errors" "^1.0.0" - cross-fetch "^3.1.5" + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" -"@backstage/catalog-model@^1.0.0", "@backstage/catalog-model@^1.0.3": - version "1.0.3" - resolved "https://registry.npmjs.org/@backstage/catalog-model/-/catalog-model-1.0.3.tgz#0d7bd832add56650871b95894878540fc41a4ef9" - integrity sha512-rbXdA/CI8EzpsthlSI4JonLd4RZoki7IN6tFvivjKDMlW8IVb63BJXWO4VnvHH+LLYzH4/OaL051YeoaicdqYw== +"@backstage/core-components@^0.10.0": + version "0.10.0" + resolved "https://registry.npmjs.org/@backstage/core-components/-/core-components-0.10.0.tgz#d7f802eee82c49677f5d9b63d8c33b7405096caa" + integrity sha512-aG41uf05Jrq44nv8i9WyzRGMEKmQmM1n0MRKz4YUhBksFexXMd+pPST7D9aSFivNm/92o7obPLjcKfx2QYbJqg== dependencies: "@backstage/config" "^1.0.1" - "@backstage/errors" "^1.0.0" - "@backstage/types" "^1.0.0" - ajv "^8.10.0" - json-schema "^0.4.0" - lodash "^4.17.21" - uuid "^8.0.0" - -"@backstage/core-components@^0.9.0", "@backstage/core-components@^0.9.5": - version "0.9.5" - resolved "https://registry.npmjs.org/@backstage/core-components/-/core-components-0.9.5.tgz#5a0b34867aaee0549bfa67b39a69c09588fa3c7a" - integrity sha512-kfAdN70idiEqHeH9ZQryn6C0RxJEKiRc/7srYIz0CVV88zJfc0nmZ5C/S10Gkht2xWfm95tTSw2P1vEYIBbfxg== - dependencies: - "@backstage/config" "^1.0.1" - "@backstage/core-plugin-api" "^1.0.3" - "@backstage/errors" "^1.0.0" - "@backstage/theme" "^0.2.15" + "@backstage/core-plugin-api" "^1.0.4" + "@backstage/errors" "^1.1.0" + "@backstage/theme" "^0.2.16" "@backstage/version-bridge" "^1.0.1" "@material-table/core" "^3.1.0" "@material-ui/core" "^4.12.2" "@material-ui/icons" "^4.9.1" "@material-ui/lab" "4.0.0-alpha.57" - "@react-hookz/web" "^14.0.0" + "@react-hookz/web" "^15.0.0" "@types/react-sparklines" "^1.7.0" "@types/react-text-truncate" "^0.14.0" ansi-regex "^6.0.1" @@ -1591,7 +2069,7 @@ pluralize "^8.0.0" prop-types "^15.7.2" qs "^6.9.4" - rc-progress "3.3.3" + rc-progress "3.4.0" react-helmet "6.1.0" react-hook-form "^7.12.2" react-markdown "^8.0.0" @@ -1607,171 +2085,6 @@ zen-observable "^0.8.15" zod "^3.11.6" -"@backstage/core-plugin-api@^1.0.0", "@backstage/core-plugin-api@^1.0.3": - version "1.0.3" - resolved "https://registry.npmjs.org/@backstage/core-plugin-api/-/core-plugin-api-1.0.3.tgz#32ecfec2afe1a25d02d41f1813621843121c2d7a" - integrity sha512-4/d9+c+AmqhY5KqsC8ikIcMsmXIcKP3+1/uT2H3/DxxJLx2sH7BvNVVqro5ZAhA7iNsuYdrfV0fHeNxGsdLuNA== - dependencies: - "@backstage/config" "^1.0.1" - "@backstage/types" "^1.0.0" - "@backstage/version-bridge" "^1.0.1" - history "^5.0.0" - prop-types "^15.7.2" - react-router-dom "6.0.0-beta.0" - zen-observable "^0.8.15" - -"@backstage/errors@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@backstage/errors/-/errors-1.0.0.tgz#08ebf53afdeaca32362955ea8551e8ffa0bb3cd7" - integrity sha512-2SpjdhH9ZOQ4RGEeu3/A7ARkl/1E9E6uBGQZ2DZOU4azTK1UZG/HE1KBMOThp3jL/8is2vOIJZLBA3r3DxLfVw== - dependencies: - "@backstage/types" "^1.0.0" - cross-fetch "^3.1.5" - serialize-error "^8.0.1" - -"@backstage/integration-react@^1.0.0": - version "1.1.1" - resolved "https://registry.npmjs.org/@backstage/integration-react/-/integration-react-1.1.1.tgz#936fd1441c47709fa8825360ea14ada26046b910" - integrity sha512-vCXErMhj90eW74A9gQwgKrc0Go5RXSEyM1wQV6+S91CZHYc3fdQJAfrxcmmUybGFtX2a2Yrmm67K8owG9WaYnQ== - dependencies: - "@backstage/config" "^1.0.1" - "@backstage/core-components" "^0.9.5" - "@backstage/core-plugin-api" "^1.0.3" - "@backstage/integration" "^1.2.1" - "@backstage/theme" "^0.2.15" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.9.1" - "@material-ui/lab" "4.0.0-alpha.57" - react-use "^17.2.4" - -"@backstage/integration@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@backstage/integration/-/integration-1.2.1.tgz#a1931d240c2fbd304f0b87d54272709f4ffe83ed" - integrity sha512-9rXD1iIGhKRCfowxWx9sRKxiv1JvDI6ucvtUeXIj1G27kT/Xy7uUcgB8CkVxsvSeog5Z1VdYkFkDmQbKQ6GPrg== - dependencies: - "@backstage/config" "^1.0.1" - "@backstage/errors" "^1.0.0" - "@octokit/auth-app" "^3.4.0" - "@octokit/rest" "^18.5.3" - cross-fetch "^3.1.5" - git-url-parse "^11.6.0" - lodash "^4.17.21" - luxon "^2.0.2" - -"@backstage/plugin-catalog-common@^1.0.3": - version "1.0.3" - resolved "https://registry.npmjs.org/@backstage/plugin-catalog-common/-/plugin-catalog-common-1.0.3.tgz#96b1de2847fec0533c49ee19f93781777eedfd0d" - integrity sha512-Sf5IQocTRQaTh9ofZUy4/szWwDl5Eek6odKVx6v33jrMot5i3grybOELrVM3/Kgcr+5/ixSSopgQPUFO/T9KBA== - dependencies: - "@backstage/plugin-permission-common" "^0.6.2" - "@backstage/plugin-search-common" "^0.3.5" - -"@backstage/plugin-catalog-react@^1.0.0", "@backstage/plugin-catalog-react@^1.1.1": - version "1.1.1" - resolved "https://registry.npmjs.org/@backstage/plugin-catalog-react/-/plugin-catalog-react-1.1.1.tgz#0441bcf1291349ad355ff51e28245d7ea26a3e01" - integrity sha512-HxowTsFaNmAp+TEb0YgBak/61SkwwRV3tUdF5O2dQugbgI3Ci8dMjN2J18LiOEFS13m6IlrCpNC1Db3QMRjwBA== - dependencies: - "@backstage/catalog-client" "^1.0.3" - "@backstage/catalog-model" "^1.0.3" - "@backstage/core-components" "^0.9.5" - "@backstage/core-plugin-api" "^1.0.3" - "@backstage/errors" "^1.0.0" - "@backstage/integration" "^1.2.1" - "@backstage/plugin-catalog-common" "^1.0.3" - "@backstage/plugin-permission-common" "^0.6.2" - "@backstage/plugin-permission-react" "^0.4.2" - "@backstage/theme" "^0.2.15" - "@backstage/types" "^1.0.0" - "@backstage/version-bridge" "^1.0.1" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.9.1" - "@material-ui/lab" "4.0.0-alpha.57" - classnames "^2.2.6" - jwt-decode "^3.1.0" - lodash "^4.17.21" - qs "^6.9.4" - react-router "6.0.0-beta.0" - react-use "^17.2.4" - yaml "^1.10.0" - zen-observable "^0.8.15" - -"@backstage/plugin-home@^0.4.19", "@backstage/plugin-home@^0.4.22": - version "0.4.22" - resolved "https://registry.npmjs.org/@backstage/plugin-home/-/plugin-home-0.4.22.tgz#efc54ebffb83a2a36dcd43e65142c30be5d8559d" - integrity sha512-0LPCyz1/nJraVdq+vkpS8g+8rnVTqY9oz5a+tOEnA6Beldlnd1xGa/qYfaH7s/5jFjd+XQRYoNw7qvioHLC16Q== - dependencies: - "@backstage/catalog-model" "^1.0.3" - "@backstage/config" "^1.0.1" - "@backstage/core-components" "^0.9.5" - "@backstage/core-plugin-api" "^1.0.3" - "@backstage/plugin-catalog-react" "^1.1.1" - "@backstage/plugin-stack-overflow" "^0.1.2" - "@backstage/theme" "^0.2.15" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.9.1" - "@material-ui/lab" "4.0.0-alpha.57" - lodash "^4.17.21" - react-router "6.0.0-beta.0" - react-use "^17.2.4" - -"@backstage/plugin-permission-common@^0.6.2": - version "0.6.2" - resolved "https://registry.npmjs.org/@backstage/plugin-permission-common/-/plugin-permission-common-0.6.2.tgz#2ab5cf3d8a4a3394edc0d552719df4f34804bfbb" - integrity sha512-tbKjm0xw6stoaFzeWL59XRz/yEEXxnBMgm3ioNbh0Qdbj44z8KivjkDjWPovI5DW6x0jFxzLQYCNMlZxOpqL6A== - dependencies: - "@backstage/config" "^1.0.1" - "@backstage/errors" "^1.0.0" - cross-fetch "^3.1.5" - uuid "^8.0.0" - zod "^3.11.6" - -"@backstage/plugin-permission-react@^0.4.2": - version "0.4.2" - resolved "https://registry.npmjs.org/@backstage/plugin-permission-react/-/plugin-permission-react-0.4.2.tgz#efc39619617e5800a68728871b87c772a0861711" - integrity sha512-isofTbK1gFgLTgr51efbFO0jWOkhQwzErL24pwY6gFVKnz7Z53AfGv1lHabxAWnNhEyTzLPMA/7s7lKuKEtOXw== - dependencies: - "@backstage/config" "^1.0.1" - "@backstage/core-plugin-api" "^1.0.3" - "@backstage/plugin-permission-common" "^0.6.2" - cross-fetch "^3.1.5" - react-router "6.0.0-beta.0" - react-use "^17.2.4" - swr "^1.1.2" - -"@backstage/plugin-search-common@^0.3.5": - version "0.3.5" - resolved "https://registry.npmjs.org/@backstage/plugin-search-common/-/plugin-search-common-0.3.5.tgz#6a374541f2bd7d9545e29abbaecc70e7ad1b5ea3" - integrity sha512-sq7IDjCLrgZQHBFi+lFVkna3lLRA5eldiTbit/rCUCO4Eq52lWdQHLrQAhsyuObmIWHDh6R2lp2qoL6aAC2AOg== - dependencies: - "@backstage/plugin-permission-common" "^0.6.2" - "@backstage/types" "^1.0.0" - -"@backstage/plugin-stack-overflow@^0.1.2": - version "0.1.2" - resolved "https://registry.npmjs.org/@backstage/plugin-stack-overflow/-/plugin-stack-overflow-0.1.2.tgz#bc140bb22d239a7106f91ea1d4c637551dc91ca5" - integrity sha512-6phLbR7E/iZjuNFFStsO2zcJYDijPTS8WEyxhM/rX1Q/OeliMgGBs8V4j1hfHgcjjLz4PPI+EDz/+eeDMi1c4w== - dependencies: - "@backstage/config" "^1.0.1" - "@backstage/core-components" "^0.9.5" - "@backstage/core-plugin-api" "^1.0.3" - "@backstage/plugin-home" "^0.4.22" - "@backstage/plugin-search-common" "^0.3.5" - "@backstage/theme" "^0.2.15" - "@material-ui/core" "^4.12.2" - "@material-ui/icons" "^4.9.1" - "@testing-library/jest-dom" "^5.10.1" - cross-fetch "^3.1.5" - lodash "^4.17.21" - qs "^6.9.4" - react-use "^17.2.4" - -"@backstage/theme@^0.2.15", "@backstage/theme@^0.2.6", "@backstage/theme@^0.2.7", "@backstage/theme@^0.2.9": - version "0.2.15" - resolved "https://registry.npmjs.org/@backstage/theme/-/theme-0.2.15.tgz#478491c9bca9dca85d5af08767ba512eabcd3669" - integrity sha512-Srl5q0X47tFofw6wuElkUqtlbYSfA3J3zlfN6jcQF4801mTrFRw+pVxZmrdxayt4gUzCN+me3mO7tij6F6xQUQ== - dependencies: - "@material-ui/core" "^4.12.2" - "@balena/dockerignore@^1.0.2": version "1.0.2" resolved "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" @@ -1787,16 +2100,16 @@ resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.0.tgz#fe364f025ba74f6de6c837a84ef44bdb1d61e68f" integrity sha512-mgmE7XBYY/21erpzhexk4Cj1cyTQ9LzvnTxtzM17BJ7ERMNE6W72mQRo0I1Ud8eFJ+RVVIcBNhLFZ3GX4XFz5w== -"@changesets/apply-release-plan@^6.0.1": - version "6.0.1" - resolved "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-6.0.1.tgz#7d7b13d4dc1f03e287bc563e029ed0bf955332a9" - integrity sha512-KGtai19+Uo7k8uco9m+hIPGoet9E6eZq15RIeHoivvgwwI66AC6ievbUO5h0NqGlZjBWnYJQNkuT66kvBYzxsA== +"@changesets/apply-release-plan@^6.0.4": + version "6.0.4" + resolved "https://registry.npmjs.org/@changesets/apply-release-plan/-/apply-release-plan-6.0.4.tgz#c08628cf5381be1aad3de69e255c68f658b4ca1a" + integrity sha512-PutV/ymf8cZMqvaLe/Lh5cP3kBQ9FZl6oGQ3qRDxWD1ML+/uH3jrCE7S7Zw7IVSXkD0lnMD+1dAX7fsOJ6ZvgA== dependencies: "@babel/runtime" "^7.10.4" - "@changesets/config" "^2.0.1" + "@changesets/config" "^2.1.1" "@changesets/get-version-range-type" "^0.3.2" - "@changesets/git" "^1.3.2" - "@changesets/types" "^5.0.0" + "@changesets/git" "^1.4.1" + "@changesets/types" "^5.1.0" "@manypkg/get-packages" "^1.1.3" detect-indent "^6.0.0" fs-extra "^7.0.1" @@ -1806,44 +2119,44 @@ resolve-from "^5.0.0" semver "^5.4.1" -"@changesets/assemble-release-plan@^5.1.3": - version "5.1.3" - resolved "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-5.1.3.tgz#b415c5db64e5a30c53aed8c1adc5ab4c4aaad283" - integrity sha512-I+TTkUoqvxBEuDLoJfJYKDXIJ+nyiTbVJ8KGhpXEsLq4N/ms/AStSbouJwF2d/p3cB+RCPr5+gXh31GSN4kA7w== +"@changesets/assemble-release-plan@^5.2.1": + version "5.2.1" + resolved "https://registry.npmjs.org/@changesets/assemble-release-plan/-/assemble-release-plan-5.2.1.tgz#b66df8d4a5615d4d904b75f7b60faeb64eb1d506" + integrity sha512-d6ckasOWlKF9Mzs82jhl6TKSCgVvfLoUK1ERySrTg2TQJdrVUteZue6uEIYUTA7SgMu67UOSwol6R9yj1nTdjw== dependencies: "@babel/runtime" "^7.10.4" "@changesets/errors" "^0.1.4" - "@changesets/get-dependents-graph" "^1.3.2" - "@changesets/types" "^5.0.0" + "@changesets/get-dependents-graph" "^1.3.3" + "@changesets/types" "^5.1.0" "@manypkg/get-packages" "^1.1.3" semver "^5.4.1" -"@changesets/changelog-git@^0.1.11": - version "0.1.11" - resolved "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.1.11.tgz#80eb45d3562aba2164f25ccc31ac97b9dcd1ded3" - integrity sha512-sWJvAm+raRPeES9usNpZRkooeEB93lOpUN0Lmjz5vhVAb7XGIZrHEJ93155bpE1S0c4oJ5Di9ZWgzIwqhWP/Wg== +"@changesets/changelog-git@^0.1.12": + version "0.1.12" + resolved "https://registry.npmjs.org/@changesets/changelog-git/-/changelog-git-0.1.12.tgz#5393f74ce9591c25d6a632c20184e92ae343db0d" + integrity sha512-Xv2CPjTBmwjl8l4ZyQ3xrsXZMq8WafPUpEonDpTmcb24XY8keVzt7ZSCJuDz035EiqrjmDKDhODoQ6XiHudlig== dependencies: - "@changesets/types" "^5.0.0" + "@changesets/types" "^5.1.0" "@changesets/cli@^2.14.0": - version "2.23.2" - resolved "https://registry.npmjs.org/@changesets/cli/-/cli-2.23.2.tgz#f32d3d9388816721419cff204010b64a864c950e" - integrity sha512-o7CWC+mcwOmA3yK5axqHOSYPYEjX/x+nq/s9aX78AyzH1SQZa6L5HX4P9uUXibyjcKynklkmusxv8vN8+hJggA== + version "2.24.3" + resolved "https://registry.npmjs.org/@changesets/cli/-/cli-2.24.3.tgz#e6d8ab5d831d2249ca482955232a9a1c9ff02c21" + integrity sha512-okhRV+0WCQJa2Kmil/WvN5TK1o3+1JYSjrsGHqhjv+PYcDgDDgQ6I9J9OMBO9lfmNIpN7xSO80/BzxgvReO4Wg== dependencies: "@babel/runtime" "^7.10.4" - "@changesets/apply-release-plan" "^6.0.1" - "@changesets/assemble-release-plan" "^5.1.3" - "@changesets/changelog-git" "^0.1.11" - "@changesets/config" "^2.0.1" + "@changesets/apply-release-plan" "^6.0.4" + "@changesets/assemble-release-plan" "^5.2.1" + "@changesets/changelog-git" "^0.1.12" + "@changesets/config" "^2.1.1" "@changesets/errors" "^0.1.4" - "@changesets/get-dependents-graph" "^1.3.2" - "@changesets/get-release-plan" "^3.0.10" - "@changesets/git" "^1.3.2" + "@changesets/get-dependents-graph" "^1.3.3" + "@changesets/get-release-plan" "^3.0.14" + "@changesets/git" "^1.4.1" "@changesets/logger" "^0.0.5" - "@changesets/pre" "^1.0.11" - "@changesets/read" "^0.5.5" - "@changesets/types" "^5.0.0" - "@changesets/write" "^0.1.8" + "@changesets/pre" "^1.0.12" + "@changesets/read" "^0.5.7" + "@changesets/types" "^5.1.0" + "@changesets/write" "^0.1.9" "@manypkg/get-packages" "^1.1.3" "@types/is-ci" "^3.0.0" "@types/semver" "^6.0.0" @@ -1864,15 +2177,15 @@ term-size "^2.1.0" tty-table "^4.1.5" -"@changesets/config@^2.0.1": - version "2.0.1" - resolved "https://registry.npmjs.org/@changesets/config/-/config-2.0.1.tgz#9c71f01032f8b12237a18edeac2a39e6142e8a50" - integrity sha512-rJaQWqsjM54T7bDiCoMDcgOuY2HzyovvRs68C//C+tYgbHyjs00JcNVcScjlV47hATrNG1AI8qTD7V9bcO/1cg== +"@changesets/config@^2.1.1": + version "2.1.1" + resolved "https://registry.npmjs.org/@changesets/config/-/config-2.1.1.tgz#96c1fec5dcccb4f6d37b56bba64e5c4f3285cca6" + integrity sha512-nSRINMqHpdtBpNVT9Eh9HtmLhOwOTAeSbaqKM5pRmGfsvyaROTBXV84ujF9UsWNlV71YxFbxTbeZnwXSGQlyTw== dependencies: "@changesets/errors" "^0.1.4" - "@changesets/get-dependents-graph" "^1.3.2" + "@changesets/get-dependents-graph" "^1.3.3" "@changesets/logger" "^0.0.5" - "@changesets/types" "^5.0.0" + "@changesets/types" "^5.1.0" "@manypkg/get-packages" "^1.1.3" fs-extra "^7.0.1" micromatch "^4.0.2" @@ -1884,28 +2197,28 @@ dependencies: extendable-error "^0.1.5" -"@changesets/get-dependents-graph@^1.3.2": - version "1.3.2" - resolved "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-1.3.2.tgz#f3ec7ce75f4afb6e3e4b6a87fde065f552c85998" - integrity sha512-tsqA6qZRB86SQuApSoDvI8yEWdyIlo/WLI4NUEdhhxLMJ0dapdeT6rUZRgSZzK1X2nv5YwR0MxQBbDAiDibKrg== +"@changesets/get-dependents-graph@^1.3.3": + version "1.3.3" + resolved "https://registry.npmjs.org/@changesets/get-dependents-graph/-/get-dependents-graph-1.3.3.tgz#9b8011d9993979a1f039ee6ce70793c81f780fea" + integrity sha512-h4fHEIt6X+zbxdcznt1e8QD7xgsXRAXd2qzLlyxoRDFSa6SxJrDAUyh7ZUNdhjBU4Byvp4+6acVWVgzmTy4UNQ== dependencies: - "@changesets/types" "^5.0.0" + "@changesets/types" "^5.1.0" "@manypkg/get-packages" "^1.1.3" chalk "^2.1.0" fs-extra "^7.0.1" semver "^5.4.1" -"@changesets/get-release-plan@^3.0.10": - version "3.0.10" - resolved "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-3.0.10.tgz#badbea8c113c976486d2eebaa66126a7ddd7ff0c" - integrity sha512-QeKHeo+mX1baRy3OIHQePMPebPFymq/ZxS6Bk3Y3FXiU+pXVnjrfqARj1E4xQT5c+48u6ISqJ8tW5f3EZ1/hng== +"@changesets/get-release-plan@^3.0.14": + version "3.0.14" + resolved "https://registry.npmjs.org/@changesets/get-release-plan/-/get-release-plan-3.0.14.tgz#b4423028a90c63feec12e22c48078f106f8d01f4" + integrity sha512-xzSfeyIOvUnbqMuQXVKTYUizreWQfICwoQpvEHoePVbERLocc1tPo5lzR7dmVCFcaA/DcnbP6mxyioeq+JuzSg== dependencies: "@babel/runtime" "^7.10.4" - "@changesets/assemble-release-plan" "^5.1.3" - "@changesets/config" "^2.0.1" - "@changesets/pre" "^1.0.11" - "@changesets/read" "^0.5.5" - "@changesets/types" "^5.0.0" + "@changesets/assemble-release-plan" "^5.2.1" + "@changesets/config" "^2.1.1" + "@changesets/pre" "^1.0.12" + "@changesets/read" "^0.5.7" + "@changesets/types" "^5.1.0" "@manypkg/get-packages" "^1.1.3" "@changesets/get-version-range-type@^0.3.2": @@ -1913,14 +2226,14 @@ resolved "https://registry.npmjs.org/@changesets/get-version-range-type/-/get-version-range-type-0.3.2.tgz#8131a99035edd11aa7a44c341cbb05e668618c67" integrity sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg== -"@changesets/git@^1.3.2": - version "1.3.2" - resolved "https://registry.npmjs.org/@changesets/git/-/git-1.3.2.tgz#336051d9a6d965806b1bc473559a9a2cc70773a6" - integrity sha512-p5UL+urAg0Nnpt70DLiBe2iSsMcDubTo9fTOD/61krmcJ466MGh71OHwdAwu1xG5+NKzeysdy1joRTg8CXcEXA== +"@changesets/git@^1.4.1": + version "1.4.1" + resolved "https://registry.npmjs.org/@changesets/git/-/git-1.4.1.tgz#3f30330d94e8bcb45c4a221f34897a29cc72cd05" + integrity sha512-GWwRXEqBsQ3nEYcyvY/u2xUK86EKAevSoKV/IhELoZ13caZ1A1TSak/71vyKILtzuLnFPk5mepP5HjBxr7lZ9Q== dependencies: "@babel/runtime" "^7.10.4" "@changesets/errors" "^0.1.4" - "@changesets/types" "^5.0.0" + "@changesets/types" "^5.1.0" "@manypkg/get-packages" "^1.1.3" is-subdir "^1.1.1" spawndamnit "^2.0.0" @@ -1932,35 +2245,35 @@ dependencies: chalk "^2.1.0" -"@changesets/parse@^0.3.13": - version "0.3.13" - resolved "https://registry.npmjs.org/@changesets/parse/-/parse-0.3.13.tgz#82788c1fc18da4750b07357a7a06142d0d975aa1" - integrity sha512-wh9Ifa0dungY6d2nMz6XxF6FZ/1I7j+mEgPAqrIyKS64nifTh1Ua82qKKMMK05CL7i4wiB2NYc3SfnnCX3RVeA== +"@changesets/parse@^0.3.14": + version "0.3.14" + resolved "https://registry.npmjs.org/@changesets/parse/-/parse-0.3.14.tgz#97321604206db2572c17a12ed37671d9ee6d5e14" + integrity sha512-SWnNVyC9vz61ueTbuxvA6b4HXcSx2iaWr2VEa37lPg1Vw+cEyQp7lOB219P7uow1xFfdtIEEsxbzXnqLAAaY8w== dependencies: - "@changesets/types" "^5.0.0" + "@changesets/types" "^5.1.0" js-yaml "^3.13.1" -"@changesets/pre@^1.0.11": - version "1.0.11" - resolved "https://registry.npmjs.org/@changesets/pre/-/pre-1.0.11.tgz#46a56790fdceabd03407559bbf91340c8e83fb6a" - integrity sha512-CXZnt4SV9waaC9cPLm7818+SxvLKIDHUxaiTXnJYDp1c56xIexx1BNfC1yMuOdzO2a3rAIcZua5Odxr3dwSKfg== +"@changesets/pre@^1.0.12": + version "1.0.12" + resolved "https://registry.npmjs.org/@changesets/pre/-/pre-1.0.12.tgz#1eaeef1a264b32c24d85dc15cf5445c1aa8b87c6" + integrity sha512-RFzWYBZx56MtgMesXjxx7ymyI829/rcIw/41hvz3VJPnY8mDscN7RJyYu7Xm7vts2Fcd+SRcO0T/Ws3I1/6J7g== dependencies: "@babel/runtime" "^7.10.4" "@changesets/errors" "^0.1.4" - "@changesets/types" "^5.0.0" + "@changesets/types" "^5.1.0" "@manypkg/get-packages" "^1.1.3" fs-extra "^7.0.1" -"@changesets/read@^0.5.5": - version "0.5.5" - resolved "https://registry.npmjs.org/@changesets/read/-/read-0.5.5.tgz#9ed90ef3e9f1ba3436ba5580201854a3f4163058" - integrity sha512-bzonrPWc29Tsjvgh+8CqJ0apQOwWim0zheeD4ZK44ApSa/GudnZJTODtA3yNOOuQzeZmL0NUebVoHIurtIkA7w== +"@changesets/read@^0.5.7": + version "0.5.7" + resolved "https://registry.npmjs.org/@changesets/read/-/read-0.5.7.tgz#ad2454ba8e2dfceb1230102aacffcbbe4d3d4291" + integrity sha512-Iteg0ccTPpkJ+qFzY97k7qqdVE5Kz30TqPo9GibpBk2g8tcLFUqf+Qd0iXPLcyhUZpPL1U6Hia1gINHNKIKx4g== dependencies: "@babel/runtime" "^7.10.4" - "@changesets/git" "^1.3.2" + "@changesets/git" "^1.4.1" "@changesets/logger" "^0.0.5" - "@changesets/parse" "^0.3.13" - "@changesets/types" "^5.0.0" + "@changesets/parse" "^0.3.14" + "@changesets/types" "^5.1.0" chalk "^2.1.0" fs-extra "^7.0.1" p-filter "^2.1.0" @@ -1970,18 +2283,18 @@ resolved "https://registry.npmjs.org/@changesets/types/-/types-4.1.0.tgz#fb8f7ca2324fd54954824e864f9a61a82cb78fe0" integrity sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw== -"@changesets/types@^5.0.0": - version "5.0.0" - resolved "https://registry.npmjs.org/@changesets/types/-/types-5.0.0.tgz#d5eb52d074bc0358ce47d54bca54370b907812a0" - integrity sha512-IT1kBLSbAgTS4WtpU6P5ko054hq12vk4tgeIFRVE7Vnm4a/wgbNvBalgiKP0MjEXbCkZbItiGQHkCGxYWR55sA== +"@changesets/types@^5.1.0": + version "5.1.0" + resolved "https://registry.npmjs.org/@changesets/types/-/types-5.1.0.tgz#e0733b69ddc3efb68524d374d3c44f53a543c8d5" + integrity sha512-uUByGATZCdaPkaO9JkBsgGDjEvHyY2Sb0e/J23+cwxBi5h0fxpLF/HObggO/Fw8T2nxK6zDfJbPsdQt5RwYFJA== -"@changesets/write@^0.1.8": - version "0.1.8" - resolved "https://registry.npmjs.org/@changesets/write/-/write-0.1.8.tgz#feed408f644c496bc52afc4dd1353670b4152ecb" - integrity sha512-oIHeFVMuP6jf0TPnKPpaFpvvAf3JBc+s2pmVChbeEgQTBTALoF51Z9kqxQfG4XONZPHZnqkmy564c7qohhhhTQ== +"@changesets/write@^0.1.9": + version "0.1.9" + resolved "https://registry.npmjs.org/@changesets/write/-/write-0.1.9.tgz#ac9315d5985f83b251820b8a046155c14a9d21f4" + integrity sha512-E90ZrsrfJVOOQaP3Mm5Xd7uDwBAqq3z5paVEavTHKA8wxi7NAL8CmjgbGxSFuiP7ubnJA2BuHlrdE4z86voGOg== dependencies: "@babel/runtime" "^7.10.4" - "@changesets/types" "^5.0.0" + "@changesets/types" "^5.1.0" fs-extra "^7.0.1" human-id "^1.0.2" prettier "^1.19.1" @@ -2007,9 +2320,9 @@ "@lezer/common" "^1.0.0" "@codemirror/language@^6.0.0": - version "6.2.0" - resolved "https://registry.npmjs.org/@codemirror/language/-/language-6.2.0.tgz#f8d103927bb61346e93781b1ca7d3f4ac3c9280b" - integrity sha512-tabB0Ef/BflwoEmTB4a//WZ9P90UQyne9qWB9YFsmeS4bnEqSys7UpGk/da1URMXhyfuzWCwp+AQNMhvu8SfnA== + version "6.2.1" + resolved "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz#cb10cd785a76e50ecd2fe2dc59ff66af8a41b87a" + integrity sha512-MC3svxuvIj0MRpFlGHxLS6vPyIdbTr2KKPEW46kCoCXw2ktb4NTkpkPBI/lSP/FoNXLCBJ0mrnUi1OoZxtpW1Q== dependencies: "@codemirror/state" "^6.0.0" "@codemirror/view" "^6.0.0" @@ -2059,9 +2372,9 @@ "@lezer/highlight" "^1.0.0" "@codemirror/view@^6.0.0": - version "6.0.3" - resolved "https://registry.npmjs.org/@codemirror/view/-/view-6.0.3.tgz#c0f6cf5c66d76cbe64227717708a714338ac76a4" - integrity sha512-1gDBymhbx2DZzwnR/rNUu1LiQqjxBJtFiB+4uLR6tHQ6vKhTIwUsP5uZUQ7SM7JxVx3UihMynnTqjcsC+mczZg== + version "6.2.0" + resolved "https://registry.npmjs.org/@codemirror/view/-/view-6.2.0.tgz#bae4c486a84174bd9656af9c9d2bd709d5b26c9f" + integrity sha512-3emW1symh+GoteFMBPsltjmF790U/trouLILATh3JodbF/z98HvcQh2g3+H6dfNIHx16uNonsAF4mNzVr1TJNA== dependencies: "@codemirror/state" "^6.0.0" style-mod "^4.0.0" @@ -2210,6 +2523,11 @@ ts-node "^9" tslib "^2" +"@esbuild/linux-loong64@0.14.54": + version "0.14.54" + resolved "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.54.tgz#de2a4be678bd4d0d1ffbb86e6de779cde5999028" + integrity sha512-bZBrLAIX1kpWelV0XemxBZllyRmM6vgFQQG2GdNb+r3Fkp0FOh1NJSvekXDs7jq70k4euu1cryLMfU+mTXlEpw== + "@eslint/eslintrc@^1.3.0": version "1.3.0" resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" @@ -2291,15 +2609,15 @@ dependencies: google-gax "^3.0.1" -"@google-cloud/firestore@^5.0.2": - version "5.0.2" - resolved "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-5.0.2.tgz#36923fde45987f928a220d347f341c5602f9e340" - integrity sha512-xlGcNYaW0nvUMzNn2+pLfbEBVt6oysVqtM89faMgZWkWfEtvIQGS0h5PRdLlcqufNzRCX3yIGv29Pb+03ys+VA== +"@google-cloud/firestore@^6.0.0": + version "6.0.0" + resolved "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-6.0.0.tgz#dade2c401237932de968fe9065d16ee2c657562b" + integrity sha512-5yBLdYIhIRANBRqAGUwN7vd6yDFqntdSGwc7ghT6ikZIRYVHW3QP6LPHYaPLQPRU0dRLLAzJIpiCY/pFGKiSNw== dependencies: fast-deep-equal "^3.1.1" functional-red-black-tree "^1.0.1" - google-gax "^2.24.1" - protobufjs "^6.8.6" + google-gax "^3.0.1" + protobufjs "^7.0.0" "@google-cloud/paginator@^3.0.7": version "3.0.7" @@ -2320,9 +2638,9 @@ integrity sha512-91ArYvRgXWb73YvEOBMmOcJc0bDRs5yiVHnqkwoG0f3nm7nZuipllz6e7BvFESBvjkDTBC0zMD8QxedUwNLc1A== "@google-cloud/storage@^6.0.0": - version "6.2.3" - resolved "https://registry.npmjs.org/@google-cloud/storage/-/storage-6.2.3.tgz#e3dae8708488cf2e0e4fbf0488083d9d279ee097" - integrity sha512-UJqn3Ln8wFBPLuwBaNu3PlhzQDL3EKKfP1+3mzLRQhcFqgpBSMPLDgAXxc6e9S0l0kqsi4GOuAA7fA+l/VAMjQ== + version "6.4.1" + resolved "https://registry.npmjs.org/@google-cloud/storage/-/storage-6.4.1.tgz#83334150d4e224cb48691de4d7f9c38e143a0970" + integrity sha512-lAddmRJ8tvxPykUqJfONBQA5XGwGk0vut1POXublc64+nCdB5aQMxwuBMf7J1zubx19QGpYPQwW6wR7YTWrvLw== dependencies: "@google-cloud/paginator" "^3.0.7" "@google-cloud/projectify" "^3.0.0" @@ -2339,18 +2657,16 @@ mime "^3.0.0" mime-types "^2.0.8" p-limit "^3.0.1" - pumpify "^2.0.0" retry-request "^5.0.0" - stream-events "^1.0.4" teeny-request "^8.0.0" uuid "^8.0.0" -"@graphiql/react@^0.5.2": - version "0.5.2" - resolved "https://registry.npmjs.org/@graphiql/react/-/react-0.5.2.tgz#5beb7bab57103d72efbaaace57157b11efd4b2ce" - integrity sha512-8rfyrFOrZaG/fWHE4nX7XApuiNCd89XatvdJSO1ndXDUz94W3Ob0DHKufWpxXJ7RtJUNat25K+zrLYUP+C2iQw== +"@graphiql/react@^0.10.0": + version "0.10.0" + resolved "https://registry.npmjs.org/@graphiql/react/-/react-0.10.0.tgz#8d888949dc6c9ddebe0817aeba3e2c164bfbb1bb" + integrity sha512-8Xo1O6SQps6R+mOozN7Ht85/07RwyXgJcKNeR2dWPkJz/1Lww8wVHIKM/AUpo0Aaoh6Ps3UK9ep8DDRfBT4XrQ== dependencies: - "@graphiql/toolkit" "^0.6.0" + "@graphiql/toolkit" "^0.6.1" codemirror "^5.65.3" codemirror-graphql "^1.3.2" copy-to-clipboard "^3.2.0" @@ -2359,36 +2675,36 @@ markdown-it "^12.2.0" set-value "^4.1.0" -"@graphiql/toolkit@^0.6.0": - version "0.6.0" - resolved "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.6.0.tgz#e508e58f305a976222f6adb84ab0ec748c26ab60" - integrity sha512-mbAwbt4lw2bFp9QW3NLVmh/r/ymczlcqvXk1HfvuC7Ma4h0yzrJiQauJyh1/gF5kjqevcRSquvP/YQJSvh1u6w== +"@graphiql/toolkit@^0.6.1": + version "0.6.1" + resolved "https://registry.npmjs.org/@graphiql/toolkit/-/toolkit-0.6.1.tgz#ab2ae0a401ef5a6334a5573397608c2c5867c79d" + integrity sha512-rRjbHko6aSg1RWGr3yOJQqEV1tKe8yw9mDSr/18B+eDhVLQ30yyKk2NznFUT9NmIDzWFGR2pH/0lbBhHKmUCqw== dependencies: "@n1ru4l/push-pull-async-iterable-iterator" "^3.1.0" meros "^1.1.4" "@graphql-codegen/cli@^2.3.1": - version "2.8.1" - resolved "https://registry.npmjs.org/@graphql-codegen/cli/-/cli-2.8.1.tgz#8e8f70417f3a0e87f266953c41c6424c6e76b473" - integrity sha512-o+Za1483WhnbMA5G4JJq72EeqXROsdEiDTfUTxtX1iPPebv+VMekTFfHnBCUXpes0XTeZViXTd16AX6cmtUF4Q== + version "2.11.6" + resolved "https://registry.npmjs.org/@graphql-codegen/cli/-/cli-2.11.6.tgz#3acfd7cd3bac40999ba1262063d84ca7c96172dc" + integrity sha512-0R2Bhgjt3XZTSdsn8MGGuJjDEN2z+KCo7920zLZz9boy6bQ0EyuxS9AUATePS9aC3djy2POAIPCHz8iHK68IlQ== dependencies: - "@graphql-codegen/core" "2.6.0" - "@graphql-codegen/plugin-helpers" "^2.5.0" - "@graphql-tools/apollo-engine-loader" "^7.3.1" - "@graphql-tools/code-file-loader" "^7.3.0" - "@graphql-tools/git-loader" "^7.2.0" - "@graphql-tools/github-loader" "^7.3.1" - "@graphql-tools/graphql-file-loader" "^7.4.0" - "@graphql-tools/json-file-loader" "^7.4.0" - "@graphql-tools/load" "^7.7.0" - "@graphql-tools/prisma-loader" "^7.2.2" - "@graphql-tools/url-loader" "^7.12.1" - "@graphql-tools/utils" "^8.8.0" + "@graphql-codegen/core" "2.6.2" + "@graphql-codegen/plugin-helpers" "^2.6.2" + "@graphql-tools/apollo-engine-loader" "^7.3.6" + "@graphql-tools/code-file-loader" "^7.3.1" + "@graphql-tools/git-loader" "^7.2.1" + "@graphql-tools/github-loader" "^7.3.6" + "@graphql-tools/graphql-file-loader" "^7.5.0" + "@graphql-tools/json-file-loader" "^7.4.1" + "@graphql-tools/load" "^7.7.1" + "@graphql-tools/prisma-loader" "^7.2.7" + "@graphql-tools/url-loader" "^7.13.2" + "@graphql-tools/utils" "^8.9.0" + "@whatwg-node/fetch" "^0.2.3" ansi-escapes "^4.3.1" chalk "^4.1.0" chokidar "^3.5.2" cosmiconfig "^7.0.0" - cross-undici-fetch "^0.4.11" debounce "^1.2.0" detect-indent "^6.0.0" graphql-config "^4.3.1" @@ -2404,32 +2720,32 @@ yaml "^1.10.0" yargs "^17.0.0" -"@graphql-codegen/core@2.6.0": - version "2.6.0" - resolved "https://registry.npmjs.org/@graphql-codegen/core/-/core-2.6.0.tgz#06a237892285aa6364a8ff40bb234e5b553b4489" - integrity sha512-7uZGnLCMR/pnh/5CsyI4y5bBvRndNHFs+AWpMUUjDBcjMRrMaavu37VyyYDz4/ob0BnQJt8RTBN9eArS9PLYAQ== +"@graphql-codegen/core@2.6.2": + version "2.6.2" + resolved "https://registry.npmjs.org/@graphql-codegen/core/-/core-2.6.2.tgz#29c766d2e9e5a3deeeb4f1728c1f7b1aca054a22" + integrity sha512-58T5yf9nEfAhDwN1Vz1hImqpdJ/gGpCGUaroQ5tqskZPf7eZYYVkEXbtqRZZLx1MCCKwjWX4hMtTPpHhwKCkng== dependencies: - "@graphql-codegen/plugin-helpers" "^2.5.0" - "@graphql-tools/schema" "^8.5.0" + "@graphql-codegen/plugin-helpers" "^2.6.2" + "@graphql-tools/schema" "^9.0.0" "@graphql-tools/utils" "^8.8.0" tslib "~2.4.0" "@graphql-codegen/graphql-modules-preset@^2.3.2": - version "2.4.1" - resolved "https://registry.npmjs.org/@graphql-codegen/graphql-modules-preset/-/graphql-modules-preset-2.4.1.tgz#b9c42ec3667d9f76a858563aad03fe19ab826ba6" - integrity sha512-+jNlVSCBJTT5yqBuzhX8bL1FNCWrD2XBE77YT+C+88ukqjlB+g5jaOXfXpIf1udrjJvNydQdtQ25LBUejdffgQ== + version "2.5.1" + resolved "https://registry.npmjs.org/@graphql-codegen/graphql-modules-preset/-/graphql-modules-preset-2.5.1.tgz#eb0c8c23457be866f7308b23b1d49d9d71d9a791" + integrity sha512-eA5G2++Uds11CQuSyJjNo9D5fsd8EiXJZ32hNb9jxlNriGHdwLzPVskSEPGi2avxhqGJG4XH2IZvkg4WTyD1kA== dependencies: - "@graphql-codegen/plugin-helpers" "^2.5.0" - "@graphql-codegen/visitor-plugin-common" "2.11.1" + "@graphql-codegen/plugin-helpers" "^2.6.2" + "@graphql-codegen/visitor-plugin-common" "2.12.1" "@graphql-tools/utils" "^8.8.0" change-case-all "1.0.14" parse-filepath "^1.0.2" tslib "~2.4.0" -"@graphql-codegen/plugin-helpers@^2.5.0": - version "2.5.0" - resolved "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.5.0.tgz#83601ed1a362c05c64c4fc9c538a0f801bc6318f" - integrity sha512-0jM5/14EdM4yow5v8OGOnUmRqfA1gaWkh+J5berqQUpcFYfSQXD6+Idnkiju/jjIypEN7UvbPkC7BgryWVxexA== +"@graphql-codegen/plugin-helpers@^2.6.2": + version "2.6.2" + resolved "https://registry.npmjs.org/@graphql-codegen/plugin-helpers/-/plugin-helpers-2.6.2.tgz#3c65d89fc9b61914235fc7cb14f1d48492d27944" + integrity sha512-bt5PNix0MwzWP53UdaYm6URrVMWU8RlQhrTSLFjxQ8ShS5zoTlQtpZJGZc5ONqFgKa83qbUmzXUtP8oRVVn8zw== dependencies: "@graphql-tools/utils" "^8.8.0" change-case-all "1.0.14" @@ -2438,44 +2754,44 @@ lodash "~4.17.0" tslib "~2.4.0" -"@graphql-codegen/schema-ast@^2.5.0": - version "2.5.0" - resolved "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-2.5.0.tgz#1b33a17924f0dd4c78d4f2c9dfce215d0bdd29ae" - integrity sha512-nlF4Yc7h90nmogG2E11TeFJ3/hCkb4SDMSdbJX68b1mhvVEji/kq3zWYKAQ+lAzjZ7HF94Eylm3MrZAjjpCKIA== +"@graphql-codegen/schema-ast@^2.5.1": + version "2.5.1" + resolved "https://registry.npmjs.org/@graphql-codegen/schema-ast/-/schema-ast-2.5.1.tgz#ce030ae6de5dacd745848009ba0ca18c9c30910c" + integrity sha512-tewa5DEKbglWn7kYyVBkh3J8YQ5ALqAMVmZwiVFIGOao5u66nd+e4HuFqp0u+Jpz4SJGGi0ap/oFrEvlqLjd2A== dependencies: - "@graphql-codegen/plugin-helpers" "^2.5.0" + "@graphql-codegen/plugin-helpers" "^2.6.2" "@graphql-tools/utils" "^8.8.0" tslib "~2.4.0" "@graphql-codegen/typescript-resolvers@^2.4.3": - version "2.7.1" - resolved "https://registry.npmjs.org/@graphql-codegen/typescript-resolvers/-/typescript-resolvers-2.7.1.tgz#2c0aeb8afbb5842c9d4145a1dbba8600b142c148" - integrity sha512-vFq4tn7werBF8LEk33aVRtmT8B4pOEI/59Iy7OfxcRtZd+Pn3g8xKTezI2STyBj3ZA8nf7j8vX9Dh9BgoxmV3g== + version "2.7.3" + resolved "https://registry.npmjs.org/@graphql-codegen/typescript-resolvers/-/typescript-resolvers-2.7.3.tgz#eac354fc68a796a94055b176f45d628430042285" + integrity sha512-6Yh1y7Z93H/PxF8tnUb3Bp1q+JuS31Dg5jZI1/FdXp931jW6pgK6g60+CKpxlIBcY6MNrFZkYKL/VRPTc8u00A== dependencies: - "@graphql-codegen/plugin-helpers" "^2.5.0" - "@graphql-codegen/typescript" "^2.7.1" - "@graphql-codegen/visitor-plugin-common" "2.11.1" + "@graphql-codegen/plugin-helpers" "^2.6.2" + "@graphql-codegen/typescript" "^2.7.3" + "@graphql-codegen/visitor-plugin-common" "2.12.1" "@graphql-tools/utils" "^8.8.0" auto-bind "~4.0.0" tslib "~2.4.0" -"@graphql-codegen/typescript@^2.4.2", "@graphql-codegen/typescript@^2.7.1": - version "2.7.1" - resolved "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-2.7.1.tgz#e237dd8829842282245b79ce7ea024aaa3c39afb" - integrity sha512-qF4SBMgBnLcegba2s9+zC3NwgRhU0Kv+eS8kl9G5ldEHx9Bpu2tft+lk6fjqqhExDzJT+MEOU3Ecog3BzL2R1g== +"@graphql-codegen/typescript@^2.4.2", "@graphql-codegen/typescript@^2.7.3": + version "2.7.3" + resolved "https://registry.npmjs.org/@graphql-codegen/typescript/-/typescript-2.7.3.tgz#ad786a1c74e16eca8e01e7a8f28078e1c24eeb61" + integrity sha512-EzX/acijXtbG/AwPzho2ZZWaNo00+xAbsRDP+vnT2PwQV3AYq3/5bFvjq1XfAGWbTntdmlYlIwC9hf5bI85WVA== dependencies: - "@graphql-codegen/plugin-helpers" "^2.5.0" - "@graphql-codegen/schema-ast" "^2.5.0" - "@graphql-codegen/visitor-plugin-common" "2.11.1" + "@graphql-codegen/plugin-helpers" "^2.6.2" + "@graphql-codegen/schema-ast" "^2.5.1" + "@graphql-codegen/visitor-plugin-common" "2.12.1" auto-bind "~4.0.0" tslib "~2.4.0" -"@graphql-codegen/visitor-plugin-common@2.11.1": - version "2.11.1" - resolved "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.11.1.tgz#2653e25a8888767a6422a204441083299c3a83a4" - integrity sha512-AlrtGWKn2o89SPna75ATEHYAu95MUMucgBqLgcRvK9n/PHhVAbkDrNCH5pL03fE0HLOup3GpjX8DcnFBMU46IA== +"@graphql-codegen/visitor-plugin-common@2.12.1": + version "2.12.1" + resolved "https://registry.npmjs.org/@graphql-codegen/visitor-plugin-common/-/visitor-plugin-common-2.12.1.tgz#8d2d24b572afd396381dddef7e2032b0f73c05cc" + integrity sha512-dIUrX4+i/uazyPQqXyQ8cqykgNFe1lknjnfDWFo0gnk2W8+ruuL2JpSrj/7efzFHxbYGMQrCABDCUTVLi3DcVA== dependencies: - "@graphql-codegen/plugin-helpers" "^2.5.0" + "@graphql-codegen/plugin-helpers" "^2.6.2" "@graphql-tools/optimize" "^1.3.0" "@graphql-tools/relay-operation-optimizer" "^6.5.0" "@graphql-tools/utils" "^8.8.0" @@ -2486,14 +2802,14 @@ parse-filepath "^1.0.2" tslib "~2.4.0" -"@graphql-tools/apollo-engine-loader@^7.3.1": - version "7.3.1" - resolved "https://registry.npmjs.org/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-7.3.1.tgz#535cb259fa6e0dbf1cf960e7212d58b8294bb370" - integrity sha512-PJhX4gQeoPtR2BJFYHYVLdLYkqQHB94r9IC64GamFV+kxR+jzQYZJdDTgnFZxvpvGJ7rEgYKNjcfWS+r+CQisQ== +"@graphql-tools/apollo-engine-loader@^7.3.6": + version "7.3.6" + resolved "https://registry.npmjs.org/@graphql-tools/apollo-engine-loader/-/apollo-engine-loader-7.3.6.tgz#a2bd7cbae69975bb8ccd33e7ca4c6a705671dc30" + integrity sha512-r7YU1X9Ce/sr+tPzSuZqVqlK7knGDpiRfB9HB2uVmbm+kPrlISQ0LuamFoT1g1nkfDZUNZn2p18ag512P1aVVw== dependencies: - "@graphql-tools/utils" "8.8.0" - cross-undici-fetch "^0.4.11" - sync-fetch "0.4.1" + "@ardatan/sync-fetch" "0.0.1" + "@graphql-tools/utils" "8.9.0" + "@whatwg-node/fetch" "^0.2.4" tslib "^2.4.0" "@graphql-tools/batch-execute@8.4.6": @@ -2516,13 +2832,23 @@ tslib "^2.4.0" value-or-promise "1.0.11" -"@graphql-tools/code-file-loader@^7.3.0": - version "7.3.0" - resolved "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-7.3.0.tgz#4a9cc213bb726ab049aad806a51707689bd7340a" - integrity sha512-mzevVv5JYyyRIbE6R0mxIniCAZWUGdoNYX97HdVgqChLOl2XRf9I8MarVPewHLmjLTZuWrdQx4ta4sPTLk4tUQ== +"@graphql-tools/batch-execute@8.5.1": + version "8.5.1" + resolved "https://registry.npmjs.org/@graphql-tools/batch-execute/-/batch-execute-8.5.1.tgz#fa3321d58c64041650be44250b1ebc3aab0ba7a9" + integrity sha512-hRVDduX0UDEneVyEWtc2nu5H2PxpfSfM/riUlgZvo/a/nG475uyehxR5cFGvTEPEQUKY3vGIlqvtRigzqTfCew== dependencies: - "@graphql-tools/graphql-tag-pluck" "7.3.0" - "@graphql-tools/utils" "8.8.0" + "@graphql-tools/utils" "8.9.0" + dataloader "2.1.0" + tslib "^2.4.0" + value-or-promise "1.0.11" + +"@graphql-tools/code-file-loader@^7.3.1": + version "7.3.1" + resolved "https://registry.npmjs.org/@graphql-tools/code-file-loader/-/code-file-loader-7.3.1.tgz#82cf1e7c5366fd6e084f607e6c14a4447110f035" + integrity sha512-nyr0zln7fi4E8lK98THdb8k3gPsSCiyXRFTTNhPRUCPeOD2RCpUZCClM5AB0xv8HjILAipdaxjhb2elPvnY5dw== + dependencies: + "@graphql-tools/graphql-tag-pluck" "7.3.1" + "@graphql-tools/utils" "8.9.0" globby "^11.0.3" tslib "^2.4.0" unixify "^1.0.0" @@ -2552,30 +2878,42 @@ tslib "~2.4.0" value-or-promise "1.0.11" -"@graphql-tools/git-loader@^7.2.0": - version "7.2.0" - resolved "https://registry.npmjs.org/@graphql-tools/git-loader/-/git-loader-7.2.0.tgz#d96c294818abc315d8fcd033ebb6d59afbf319f5" - integrity sha512-aFJ5Py9sCIhiSyE+EK4zC+mQ4zRUNGGNwosqlCYNcmhtGFwlXArB13/rdj2b4p3RsmTe31Mso9VfsEZXQ6CGCw== +"@graphql-tools/delegate@8.8.1": + version "8.8.1" + resolved "https://registry.npmjs.org/@graphql-tools/delegate/-/delegate-8.8.1.tgz#0653a72f38947f38ab7917dfac50ebf6a6b883e9" + integrity sha512-NDcg3GEQmdEHlnF7QS8b4lM1PSF+DKeFcIlLEfZFBvVq84791UtJcDj8734sIHLukmyuAxXMfA1qLd2l4lZqzA== dependencies: - "@graphql-tools/graphql-tag-pluck" "7.3.0" - "@graphql-tools/utils" "8.8.0" + "@graphql-tools/batch-execute" "8.5.1" + "@graphql-tools/schema" "8.5.1" + "@graphql-tools/utils" "8.9.0" + dataloader "2.1.0" + tslib "~2.4.0" + value-or-promise "1.0.11" + +"@graphql-tools/git-loader@^7.2.1": + version "7.2.1" + resolved "https://registry.npmjs.org/@graphql-tools/git-loader/-/git-loader-7.2.1.tgz#e0eaa77f1696199a780f32035646489e57a017dd" + integrity sha512-grfLO3CqKO8hlymqBQeNsjGCzjMXH+n+epM6vH2OW1tUM9UmPrH+En0BynJCap9VYVZ0KcbYz03o5ZJNYkbaCg== + dependencies: + "@graphql-tools/graphql-tag-pluck" "7.3.1" + "@graphql-tools/utils" "8.9.0" is-glob "4.0.3" micromatch "^4.0.4" tslib "^2.4.0" unixify "^1.0.0" -"@graphql-tools/github-loader@^7.3.1": - version "7.3.1" - resolved "https://registry.npmjs.org/@graphql-tools/github-loader/-/github-loader-7.3.1.tgz#faa1bf84ccafba20e9300d19155add312e63b22f" - integrity sha512-sus/YOZKhhbcBQTCWFvUdIzFThm/LiAlSh9+Bt+hNz2K05PWzR6XD7Fo2ejh6bSAZvevJBvsH/4xf1YSK86Fkg== +"@graphql-tools/github-loader@^7.3.6": + version "7.3.6" + resolved "https://registry.npmjs.org/@graphql-tools/github-loader/-/github-loader-7.3.6.tgz#9c49ef902760895cd683927b9ef358168efd4dab" + integrity sha512-TovDdZ0dxShIfnP3/02+aVfPzhYHedtCVU4GB7rajExdOlNEUAfMAjpDKgTReENzD0ZaehqBnGj2BpR+/b4C1Q== dependencies: - "@graphql-tools/graphql-tag-pluck" "7.3.0" - "@graphql-tools/utils" "8.8.0" - cross-undici-fetch "^0.4.11" - sync-fetch "0.4.1" + "@ardatan/sync-fetch" "0.0.1" + "@graphql-tools/graphql-tag-pluck" "7.3.1" + "@graphql-tools/utils" "8.9.0" + "@whatwg-node/fetch" "^0.2.4" tslib "^2.4.0" -"@graphql-tools/graphql-file-loader@^7.3.7", "@graphql-tools/graphql-file-loader@^7.4.0": +"@graphql-tools/graphql-file-loader@^7.3.7": version "7.4.0" resolved "https://registry.npmjs.org/@graphql-tools/graphql-file-loader/-/graphql-file-loader-7.4.0.tgz#c06e36248dd6a2025de65a1cfce03222ad0e74c2" integrity sha512-r1lslE5GlWO/nbDX82enHjvva7qQiZEIPm+LC9JSgKaYuVoYHuIuIAVYkpBHeaRK1Kbh/86pEhL7PuBZ/cIWSA== @@ -2586,15 +2924,26 @@ tslib "^2.4.0" unixify "^1.0.0" -"@graphql-tools/graphql-tag-pluck@7.3.0": - version "7.3.0" - resolved "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.3.0.tgz#e83b568151b2cd0f8678489bb927e2bf9cf24af9" - integrity sha512-GxtgGTSOiQuFc/yNWXsPJ5QEgGlH+4qBf1paqUJtjFpm89dZA+VkdjoIDiFg8fyXGivjZ37+XAUbuu6UlsT+6Q== +"@graphql-tools/graphql-file-loader@^7.5.0": + version "7.5.0" + resolved "https://registry.npmjs.org/@graphql-tools/graphql-file-loader/-/graphql-file-loader-7.5.0.tgz#b08e2a7c64a1fecb5fc01d557a07116a3151ee14" + integrity sha512-X3wcC+ZljbXTwdTTSp3oUHJd66mFLDKI750uhB0HidBxE6+wyw7fhmJVJiYROXPswaGliuabpo0JEyLj7hhWKA== + dependencies: + "@graphql-tools/import" "6.7.1" + "@graphql-tools/utils" "8.9.0" + globby "^11.0.3" + tslib "^2.4.0" + unixify "^1.0.0" + +"@graphql-tools/graphql-tag-pluck@7.3.1": + version "7.3.1" + resolved "https://registry.npmjs.org/@graphql-tools/graphql-tag-pluck/-/graphql-tag-pluck-7.3.1.tgz#067880a923bacbb522eab68d994975346d68ab64" + integrity sha512-+Aayl4y42ASrxDvu613lp3NiK1JRggy/m9wlo93dJp/9L5vKPYlrtFvuQ1tpPEEuSBboYNa/erOsELrRwzzakA== dependencies: "@babel/parser" "^7.16.8" "@babel/traverse" "^7.16.8" "@babel/types" "^7.16.8" - "@graphql-tools/utils" "8.8.0" + "@graphql-tools/utils" "8.9.0" tslib "^2.4.0" "@graphql-tools/import@6.7.0": @@ -2606,7 +2955,16 @@ resolve-from "5.0.0" tslib "^2.4.0" -"@graphql-tools/json-file-loader@^7.3.7", "@graphql-tools/json-file-loader@^7.4.0": +"@graphql-tools/import@6.7.1": + version "6.7.1" + resolved "https://registry.npmjs.org/@graphql-tools/import/-/import-6.7.1.tgz#bb62a109503266f25e6dd8799763eddaeba8da3a" + integrity sha512-StLosFVhdw+eZkL+v9dBabszxCAZtEYW4Oy1+750fDkH39GrmzOB8mWiYna7rm9+GMisC9atJtXuAfMF02Aoag== + dependencies: + "@graphql-tools/utils" "8.9.0" + resolve-from "5.0.0" + tslib "^2.4.0" + +"@graphql-tools/json-file-loader@^7.3.7": version "7.4.0" resolved "https://registry.npmjs.org/@graphql-tools/json-file-loader/-/json-file-loader-7.4.0.tgz#c25059ebce34db6190a11580e2bc7c66df68a7b9" integrity sha512-6oR7Ulc5iZc5SM3g1Yj91DqSu3TNbfGK/0baE8KyUlvq6KiIuWFWDy13RGnNesftt4RSWvZqGzu/kzXcBHtt+A== @@ -2616,7 +2974,17 @@ tslib "^2.4.0" unixify "^1.0.0" -"@graphql-tools/load@^7.5.5", "@graphql-tools/load@^7.7.0": +"@graphql-tools/json-file-loader@^7.4.1": + version "7.4.1" + resolved "https://registry.npmjs.org/@graphql-tools/json-file-loader/-/json-file-loader-7.4.1.tgz#40414a57195a9d4f96e25e5041d674426937e11a" + integrity sha512-+QaeRyJcvUXUNEoIaecYrABunqk8/opFbpdHPAijJyVHvlsYfqXR12/501g+/QZzGHKYnyi+Q3lsZbBboj5LBg== + dependencies: + "@graphql-tools/utils" "8.9.0" + globby "^11.0.3" + tslib "^2.4.0" + unixify "^1.0.0" + +"@graphql-tools/load@^7.5.5": version "7.7.0" resolved "https://registry.npmjs.org/@graphql-tools/load/-/load-7.7.0.tgz#668f70f09bc1c34b87c3267853cf73451897a22e" integrity sha512-6KX7Z8BtlFScDr0pIac92QZWlPGbHcpNMesX/6Y3Vsp3FeFnAYfzZldXZQcJoW7Yl+gHdFwYVq683wSH64kNrw== @@ -2626,6 +2994,16 @@ p-limit "3.1.0" tslib "^2.4.0" +"@graphql-tools/load@^7.7.1": + version "7.7.1" + resolved "https://registry.npmjs.org/@graphql-tools/load/-/load-7.7.1.tgz#937354e5123a8b0e0d59585ebca7c55165265a98" + integrity sha512-rJ2WUV41wwAkMnBgtcBym3TKVbPgz7z9tBCjOmbNVLy5bB9StVPdo2Uci0D5xYSgLV9XIt+zdyAnYGptioJeWg== + dependencies: + "@graphql-tools/schema" "8.5.1" + "@graphql-tools/utils" "8.9.0" + p-limit "3.1.0" + tslib "^2.4.0" + "@graphql-tools/merge@8.2.10": version "8.2.10" resolved "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.2.10.tgz#fe2fe5ad33dc2d1b0af8751c0c08d18bb6bb6d88" @@ -2642,6 +3020,22 @@ "@graphql-tools/utils" "8.8.0" tslib "^2.4.0" +"@graphql-tools/merge@8.3.1": + version "8.3.1" + resolved "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.1.tgz#06121942ad28982a14635dbc87b5d488a041d722" + integrity sha512-BMm99mqdNZbEYeTPK3it9r9S6rsZsQKtlqJsSBknAclXq2pGEfOxjcIZi+kBSkHZKPKCRrYDd5vY0+rUmIHVLg== + dependencies: + "@graphql-tools/utils" "8.9.0" + tslib "^2.4.0" + +"@graphql-tools/merge@8.3.3": + version "8.3.3" + resolved "https://registry.npmjs.org/@graphql-tools/merge/-/merge-8.3.3.tgz#74dd4816c3fc7af38730fc59d1cba6e687d7fb2d" + integrity sha512-EfULshN2s2s2mhBwbV9WpGnoehRLe7eIMdZrKfHhxlBWOvtNUd3KSCN0PUdAMd7lj1jXUW9KYdn624JrVn6qzg== + dependencies: + "@graphql-tools/utils" "8.10.0" + tslib "^2.4.0" + "@graphql-tools/mock@^8.1.2": version "8.6.8" resolved "https://registry.npmjs.org/@graphql-tools/mock/-/mock-8.6.8.tgz#232a23c0c14dcfca88012886230b93e6fc2303e2" @@ -2659,13 +3053,13 @@ dependencies: tslib "^2.4.0" -"@graphql-tools/prisma-loader@^7.2.2": - version "7.2.2" - resolved "https://registry.npmjs.org/@graphql-tools/prisma-loader/-/prisma-loader-7.2.2.tgz#ee56371f75a4e82330b0e4915f57976bf0f4a16a" - integrity sha512-f5txUBRwwZmPQYL5g5CNdOjOglFE/abtnEVOvUCq+nET0BRuxcuxUD5vykfZnkql9sNvnCFAfrZuBVe5S2n3bA== +"@graphql-tools/prisma-loader@^7.2.7": + version "7.2.7" + resolved "https://registry.npmjs.org/@graphql-tools/prisma-loader/-/prisma-loader-7.2.7.tgz#8b5e15b345e72c77a568281e62d8fa5c7089e513" + integrity sha512-vAu2kVqSdfuiZJFOC3bDelKFeOQLfhOHOw1PT8YC0HiJQpLuEFwiDU6eXxWrPALqZEEWfCKMM8/4hlLJv+gokA== dependencies: - "@graphql-tools/url-loader" "7.12.1" - "@graphql-tools/utils" "8.8.0" + "@graphql-tools/url-loader" "7.13.2" + "@graphql-tools/utils" "8.9.0" "@types/js-yaml" "^4.0.0" "@types/json-stable-stringify" "^1.0.32" "@types/jsonwebtoken" "^8.5.0" @@ -2680,7 +3074,6 @@ json-stable-stringify "^1.0.1" jsonwebtoken "^8.5.1" lodash "^4.17.20" - replaceall "^0.1.6" scuid "^1.1.0" tslib "^2.4.0" yaml-ast-parser "^0.0.43" @@ -2704,7 +3097,7 @@ tslib "~2.3.0" value-or-promise "1.0.11" -"@graphql-tools/schema@8.5.0", "@graphql-tools/schema@^8.5.0": +"@graphql-tools/schema@8.5.0": version "8.5.0" resolved "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.5.0.tgz#0332b3a2e674d16e9bf8a58dfd47432449ce2368" integrity sha512-VeFtKjM3SA9/hCJJfr95aEdC3G0xIKM9z0Qdz4i+eC1g2fdZYnfWFt2ucW4IME+2TDd0enHlKzaV0qk2SLVUww== @@ -2714,7 +3107,48 @@ tslib "^2.4.0" value-or-promise "1.0.11" -"@graphql-tools/url-loader@7.12.1", "@graphql-tools/url-loader@^7.12.1", "@graphql-tools/url-loader@^7.9.7": +"@graphql-tools/schema@8.5.1": + version "8.5.1" + resolved "https://registry.npmjs.org/@graphql-tools/schema/-/schema-8.5.1.tgz#c2f2ff1448380919a330312399c9471db2580b58" + integrity sha512-0Esilsh0P/qYcB5DKQpiKeQs/jevzIadNTaT0jeWklPMwNbT7yMX4EqZany7mbeRRlSRwMzNzL5olyFdffHBZg== + dependencies: + "@graphql-tools/merge" "8.3.1" + "@graphql-tools/utils" "8.9.0" + tslib "^2.4.0" + value-or-promise "1.0.11" + +"@graphql-tools/schema@^9.0.0": + version "9.0.1" + resolved "https://registry.npmjs.org/@graphql-tools/schema/-/schema-9.0.1.tgz#ba8629107c1f0b9ffad14c08c2a85961967682fd" + integrity sha512-Y6apeiBmvXEz082IAuS/ainnEEQrzMECP1MRIV72eo2WPa6ZtLYPycvIbd56Z5uU2LKP4XcWRgK6WUbCyN16Rw== + dependencies: + "@graphql-tools/merge" "8.3.3" + "@graphql-tools/utils" "8.10.0" + tslib "^2.4.0" + value-or-promise "1.0.11" + +"@graphql-tools/url-loader@7.13.2", "@graphql-tools/url-loader@^7.13.2": + version "7.13.2" + resolved "https://registry.npmjs.org/@graphql-tools/url-loader/-/url-loader-7.13.2.tgz#4663ea817aa60d3d4ce81a47a36cba8fdfff069f" + integrity sha512-4jtGecsxziiggQ9UryQB/ioqFwVkF10sKdk5bPg/fVKSkPddN5lvCgEwk20LojlDT9mDr53ME0ArMBKkvjTxBw== + dependencies: + "@ardatan/sync-fetch" "0.0.1" + "@graphql-tools/delegate" "8.8.1" + "@graphql-tools/utils" "8.9.0" + "@graphql-tools/wrap" "8.5.1" + "@n1ru4l/graphql-live-query" "^0.9.0" + "@types/ws" "^8.0.0" + "@whatwg-node/fetch" "^0.2.4" + dset "^3.1.2" + extract-files "^11.0.0" + graphql-ws "^5.4.1" + isomorphic-ws "^5.0.0" + meros "^1.1.4" + tslib "^2.4.0" + value-or-promise "^1.0.11" + ws "^8.3.0" + +"@graphql-tools/url-loader@^7.9.7": version "7.12.1" resolved "https://registry.npmjs.org/@graphql-tools/url-loader/-/url-loader-7.12.1.tgz#931a65da4faced1a71ddc5af638b87140ff3dfb6" integrity sha512-Fd3ZZLEEr9GGFHEbdrcaMHFQu01BLpFnNDBkISupvjokd497O5Uh0xZvsZGC6mxVt0WWQWpgaK2ef+oLuOdLqQ== @@ -2735,6 +3169,13 @@ value-or-promise "^1.0.11" ws "^8.3.0" +"@graphql-tools/utils@8.10.0": + version "8.10.0" + resolved "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.10.0.tgz#8e76db7487e19b60cf99fb90c2d6343b2105b331" + integrity sha512-yI+V373FdXQbYfqdarehn9vRWDZZYuvyQ/xwiv5ez2BbobHrqsexF7qs56plLRaQ8ESYpVAjMQvJWe9s23O0Jg== + dependencies: + tslib "^2.4.0" + "@graphql-tools/utils@8.6.9": version "8.6.9" resolved "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.6.9.tgz#fe1b81df29c9418b41b7a1ffe731710b93d3a1fe" @@ -2749,6 +3190,13 @@ dependencies: tslib "^2.4.0" +"@graphql-tools/utils@8.9.0", "@graphql-tools/utils@^8.9.0": + version "8.9.0" + resolved "https://registry.npmjs.org/@graphql-tools/utils/-/utils-8.9.0.tgz#c6aa5f651c9c99e1aca55510af21b56ec296cdb7" + integrity sha512-pjJIWH0XOVnYGXCqej8g/u/tsfV4LvLlj0eATKQu5zwnxd/TiTHq7Cg313qUPTFFHZ3PP5wJ15chYVtLDwaymg== + dependencies: + tslib "^2.4.0" + "@graphql-tools/wrap@8.5.0": version "8.5.0" resolved "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-8.5.0.tgz#ce1b0d775e1fc3a17404df566f4d2196d31c6e20" @@ -2760,6 +3208,17 @@ tslib "^2.4.0" value-or-promise "1.0.11" +"@graphql-tools/wrap@8.5.1": + version "8.5.1" + resolved "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-8.5.1.tgz#d4bd1f89850bb1ce0209f35f66d002080b439495" + integrity sha512-KpVVfha2wLSpE08YLX0jeo5nXPfDLASlxOqMlvfa/B4X8SOVmuLyN1L5YZ132tPLDF93uflwlHFnUO5ahpRNlA== + dependencies: + "@graphql-tools/delegate" "8.8.1" + "@graphql-tools/schema" "8.5.1" + "@graphql-tools/utils" "8.9.0" + tslib "^2.4.0" + value-or-promise "1.0.11" + "@graphql-tools/wrap@^8.3.1": version "8.4.16" resolved "https://registry.npmjs.org/@graphql-tools/wrap/-/wrap-8.4.16.tgz#87dce9ec623a921e5a62f44e75abc9655892724b" @@ -2826,15 +3285,20 @@ object-assign "^4.1.1" scheduler "^0.20.2" -"@humanwhocodes/config-array@^0.9.2": - version "0.9.2" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz#68be55c737023009dfc5fe245d51181bb6476914" - integrity sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA== +"@humanwhocodes/config-array@^0.10.4": + version "0.10.4" + resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz#01e7366e57d2ad104feea63e72248f22015c520c" + integrity sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" minimatch "^3.0.4" +"@humanwhocodes/gitignore-to-minimatch@^1.0.2": + version "1.0.2" + resolved "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" + integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== + "@humanwhocodes/object-schema@^1.2.1": version "1.2.1" resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" @@ -3405,11 +3869,33 @@ resolved "https://registry.npmjs.org/@josephg/resolvable/-/resolvable-1.0.1.tgz#69bc4db754d79e1a2f17a650d3466e038d94a5eb" integrity sha512-CtzORUwWTTOTqfVtHaKRJ0I1kNQd1bpn3sUh8I3nJDVY+5/M/Oe1DnEWzPQvqq/xPIIkzzzIP7mfCoAjFRvDhg== +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/resolve-uri@^3.0.3": version "3.1.0" resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + "@jridgewell/sourcemap-codec@^1.4.10": version "1.4.14" resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" @@ -3431,10 +3917,18 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@jridgewell/trace-mapping@^0.3.7": - version "0.3.13" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" - integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w== +"@jridgewell/trace-mapping@^0.3.14": + version "0.3.15" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz#aba35c48a38d3fd84b37e66c9c0423f9744f9774" + integrity sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.14" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== dependencies: "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" @@ -3450,9 +3944,9 @@ integrity sha512-zMM9Ds+SawiUkakS7y94Ymqx+S0ORzpG3frZirN3l+UlXUmSUR7hF4wxCVqW+ei94JzV5kt0uXBcoOEAuiydrw== "@keyv/redis@^2.2.3": - version "2.3.7" - resolved "https://registry.npmjs.org/@keyv/redis/-/redis-2.3.7.tgz#4f6f6d85be07668a976bb3c9d910c57d1ab12c70" - integrity sha512-aBxnl2Bt1D7JUXQwdO9dDOBJi3VmKO5yfIiwxvEr/hVSryho0Zn1EuWr3fi6UE8WYw5X8FPUyD6h5wuVQreQsA== + version "2.3.8" + resolved "https://registry.npmjs.org/@keyv/redis/-/redis-2.3.8.tgz#8939a91e5b5d49da43005cf363a63fe475e1a19d" + integrity sha512-zzk/6TiuxqBcQd8vJDJaxTJDrbLDNaiRlLKDgpSB+xYBjd4NJK5Fl8YIPV9A+oteroJtwGgwdML9VJRXmaus3A== dependencies: ioredis "^5.1.0" @@ -4244,7 +4738,7 @@ react-beautiful-dnd "^13.0.0" react-double-scrollbar "0.0.15" -"@material-ui/core@^4.11.0", "@material-ui/core@^4.11.3", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2", "@material-ui/core@^4.9.10", "@material-ui/core@^4.9.13": +"@material-ui/core@^4.11.0", "@material-ui/core@^4.11.3", "@material-ui/core@^4.12.1", "@material-ui/core@^4.12.2", "@material-ui/core@^4.12.4", "@material-ui/core@^4.9.10", "@material-ui/core@^4.9.13": version "4.12.4" resolved "https://registry.npmjs.org/@material-ui/core/-/core-4.12.4.tgz#4ac17488e8fcaf55eb6a7f5efb2a131e10138a73" integrity sha512-tr7xekNlM9LjA6pagJmL8QCgZXaubWUwkJnoYcMKd4gw/t4XiyvnTkjdGrUVicyB2BsdaAv1tvow45bPM4sSwQ== @@ -4291,7 +4785,7 @@ prop-types "^15.7.2" react-is "^16.8.0 || ^17.0.0" -"@material-ui/lab@^4.0.0-alpha.57", "@material-ui/lab@^4.0.0-alpha.60": +"@material-ui/lab@^4.0.0-alpha.57", "@material-ui/lab@^4.0.0-alpha.60", "@material-ui/lab@^4.0.0-alpha.61": version "4.0.0-alpha.61" resolved "https://registry.npmjs.org/@material-ui/lab/-/lab-4.0.0-alpha.61.tgz#9bf8eb389c0c26c15e40933cc114d4ad85e3d978" integrity sha512-rSzm+XKiNUjKegj8bzt5+pygZeckNLOr+IjykH8sYdVk7dE9y2ZuUSofiMV2bJk3qU+JHwexmw+q0RyNZB9ugg== @@ -4366,9 +4860,9 @@ react-is "^16.8.0 || ^17.0.0" "@maxim_mazurok/gapi.client.calendar@^3.0.20220408": - version "3.0.20220708" - resolved "https://registry.npmjs.org/@maxim_mazurok/gapi.client.calendar/-/gapi.client.calendar-3.0.20220708.tgz#b8eb22479a33df5330cb276c8d5fe9d7a88e322c" - integrity sha512-FwIIJy57HH7agFzqUOYtGWbCedw2MzGFpfnfWEvhlc/j0RNvlPVK68LagsUVoxqRXw9rflC5P3WZ0uk2VwgOmQ== + version "3.0.20220805" + resolved "https://registry.npmjs.org/@maxim_mazurok/gapi.client.calendar/-/gapi.client.calendar-3.0.20220805.tgz#ccc3c12f83b361daf5e48e0a2ff7abee5b0a6c5d" + integrity sha512-YwUDC4G4amUkM4u55wJpARowbs6AjJoF+PxxLEz3ZoHXvzP/VWPb1L0AhxnbFwDhWKVFcXkZTEGDc59PcuIJjQ== dependencies: "@types/gapi.client" "*" @@ -4413,9 +4907,9 @@ typescript "~4.6.3" "@microsoft/microsoft-graph-types@^2.6.0": - version "2.22.0" - resolved "https://registry.npmjs.org/@microsoft/microsoft-graph-types/-/microsoft-graph-types-2.22.0.tgz#7ceb222311770ed5b240d627b657d25b3979964e" - integrity sha512-iKc5L036hc/wu13DX5kGf//3/WqTAErAPTyYKG6zT3vG070xXaaP7PInODznfyZduhiOvavmrRlQb34ajeDTUA== + version "2.23.0" + resolved "https://registry.npmjs.org/@microsoft/microsoft-graph-types/-/microsoft-graph-types-2.23.0.tgz#075cd5bbd523a414bb98ab97fb2207bcccbfa532" + integrity sha512-4TwjVg/A28K5Df1br17gRmv7Z0iWqYArdUo77xPz+bEtMpDD1hwmKUNj7O7a8r3sN7WIC2nKp6Atb6LXTr1LEA== "@microsoft/tsdoc-config@~0.16.1": version "0.16.1" @@ -4811,51 +5305,22 @@ "@octokit/types" "^6.27.1" "@octokit/webhooks" "^10.0.0" -"@octokit/auth-app@^3.4.0": - version "3.6.1" - resolved "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-3.6.1.tgz#aa5b02cc211175cbc28ce6c03c73373c1206d632" - integrity sha512-6oa6CFphIYI7NxxHrdVOzhG7hkcKyGyYocg7lNDSJVauVOLtylg8hNJzoUyPAYKKK0yUeoZamE/lMs2tG+S+JA== - dependencies: - "@octokit/auth-oauth-app" "^4.3.0" - "@octokit/auth-oauth-user" "^1.2.3" - "@octokit/request" "^5.6.0" - "@octokit/request-error" "^2.1.0" - "@octokit/types" "^6.0.3" - "@types/lru-cache" "^5.1.0" - deprecation "^2.3.1" - lru-cache "^6.0.0" - universal-github-app-jwt "^1.0.1" - universal-user-agent "^6.0.0" - "@octokit/auth-app@^4.0.0": - version "4.0.4" - resolved "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-4.0.4.tgz#e774da352e7c9d0648d5d0fdf0fb75cd6a16c2af" - integrity sha512-s3MK7M9e8TD/ih8lCBTrdZ74XPHMtHV7aycCKNBRQ2QJPdMwqx0mVbmLOIuW4dCwMX7K243+JAvf52tryFHRdQ== + version "4.0.5" + resolved "https://registry.npmjs.org/@octokit/auth-app/-/auth-app-4.0.5.tgz#0e52752c37340ae8686617b7ce188e4cae6d7ba1" + integrity sha512-fCbi4L/egsP3p4p1SelOFORM/m/5KxROhHdcIW5Lb17DDdW61fGT8y3wGpfiSeYNuulwF5QIfzJ7tdgtHNAymA== dependencies: "@octokit/auth-oauth-app" "^5.0.0" "@octokit/auth-oauth-user" "^2.0.0" "@octokit/request" "^6.0.0" "@octokit/request-error" "^3.0.0" - "@octokit/types" "^6.0.3" + "@octokit/types" "^7.0.0" "@types/lru-cache" "^5.1.0" deprecation "^2.3.1" lru-cache "^6.0.0" universal-github-app-jwt "^1.0.1" universal-user-agent "^6.0.0" -"@octokit/auth-oauth-app@^4.3.0": - version "4.3.0" - resolved "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-4.3.0.tgz#de02f184360ffd7cfccef861053784fc4410e7ea" - integrity sha512-cETmhmOQRHCz6cLP7StThlJROff3A/ln67Q961GuIr9zvyFXZ4lIJy9RE6Uw5O7D8IXWPU3jhDnG47FTSGQr8Q== - dependencies: - "@octokit/auth-oauth-device" "^3.1.1" - "@octokit/auth-oauth-user" "^1.2.1" - "@octokit/request" "^5.3.0" - "@octokit/types" "^6.0.3" - "@types/btoa-lite" "^1.0.0" - btoa-lite "^1.0.0" - universal-user-agent "^6.0.0" - "@octokit/auth-oauth-app@^5.0.0": version "5.0.1" resolved "https://registry.npmjs.org/@octokit/auth-oauth-app/-/auth-oauth-app-5.0.1.tgz#294b5edd780d2fca296ade2aa21feba7690c2ac7" @@ -4889,18 +5354,6 @@ "@octokit/types" "^6.10.0" universal-user-agent "^6.0.0" -"@octokit/auth-oauth-user@^1.2.1", "@octokit/auth-oauth-user@^1.2.3": - version "1.2.4" - resolved "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-1.2.4.tgz#3594eb7d40cb462240e7e90849781dfa0045aed5" - integrity sha512-efOajupCZBP1veqx5w59Qey0lIud1rDUgxTRjjkQDU3eOBmkAasY1pXemDsQwW0I85jb1P/gn2dMejedVxf9kw== - dependencies: - "@octokit/auth-oauth-device" "^3.1.1" - "@octokit/oauth-methods" "^1.1.0" - "@octokit/request" "^5.4.14" - "@octokit/types" "^6.12.2" - btoa-lite "^1.0.0" - universal-user-agent "^6.0.0" - "@octokit/auth-oauth-user@^2.0.0": version "2.0.0" resolved "https://registry.npmjs.org/@octokit/auth-oauth-user/-/auth-oauth-user-2.0.0.tgz#7fe448bb06a4c55102098dd7105670e723d2f7ec" @@ -4921,11 +5374,11 @@ "@octokit/types" "^6.0.0" "@octokit/auth-token@^3.0.0": - version "3.0.0" - resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.0.tgz#6f22c5fc56445c496628488ba6810131558fa4a9" - integrity sha512-MDNFUBcJIptB9At7HiV7VCvU3NcL4GnfCQaP8C5lrxWrRPMJBnemYtehaKSOlaM7AYxeRyj9etenu8LVpSpVaQ== + version "3.0.1" + resolved "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.1.tgz#88bc2baf5d706cb258474e722a720a8365dff2ec" + integrity sha512-/USkK4cioY209wXRpund6HZzHo9GmjakpV9ycOkpMcMxMk7QVcVFVyCMtzvXYiHsB2crgDgrtNYSELYFBXhhaA== dependencies: - "@octokit/types" "^6.0.3" + "@octokit/types" "^7.0.0" "@octokit/auth-unauthenticated@^3.0.0": version "3.0.0" @@ -4948,15 +5401,15 @@ universal-user-agent "^6.0.0" "@octokit/core@^4.0.0": - version "4.0.2" - resolved "https://registry.npmjs.org/@octokit/core/-/core-4.0.2.tgz#4eaf9c5fd39913b541c5e31a2b8fdc3cf50480bc" - integrity sha512-vgVtE02EF9kXFsjmFoKFCwH1wDspPfDgopRbAlavkGuBJPWF+u5n0xgwP4obmdKNvLM+bB7MI7W31c2E13zgDQ== + version "4.0.5" + resolved "https://registry.npmjs.org/@octokit/core/-/core-4.0.5.tgz#589e68c0a35d2afdcd41dafceab072c2fbc6ab5f" + integrity sha512-4R3HeHTYVHCfzSAi0C6pbGXV8UDI5Rk+k3G7kLVNckswN9mvpOzW9oENfjfH3nEmzg8y3AmKmzs8Sg6pLCeOCA== dependencies: "@octokit/auth-token" "^3.0.0" - "@octokit/graphql" "^4.5.8" + "@octokit/graphql" "^5.0.0" "@octokit/request" "^6.0.0" - "@octokit/request-error" "^2.0.5" - "@octokit/types" "^6.0.3" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^7.0.0" before-after-hook "^2.2.0" universal-user-agent "^6.0.0" @@ -4974,23 +5427,23 @@ universal-user-agent "^6.0.0" "@octokit/endpoint@^6.0.1": - version "6.0.3" - resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.3.tgz#dd09b599662d7e1b66374a177ab620d8cdf73487" - integrity sha512-Y900+r0gIz+cWp6ytnkibbD95ucEzDSKzlEnaWS52hbCDNcCJYO5mRmWW7HRAnDc7am+N/5Lnd8MppSaTYx1Yg== - dependencies: - "@octokit/types" "^5.0.0" - is-plain-object "^3.0.0" - universal-user-agent "^5.0.0" - -"@octokit/endpoint@^7.0.0": - version "7.0.0" - resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.0.tgz#be758a1236d68d6bbb505e686dd50881c327a519" - integrity sha512-Kz/mIkOTjs9rV50hf/JK9pIDl4aGwAtT8pry6Rpy+hVXkAPhXanNQRxMoq6AeRgDCZR6t/A1zKniY2V1YhrzlQ== + version "6.0.12" + resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz#3b4d47a4b0e79b1027fb8d75d4221928b2d05658" + integrity sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA== dependencies: "@octokit/types" "^6.0.3" is-plain-object "^5.0.0" universal-user-agent "^6.0.0" +"@octokit/endpoint@^7.0.0": + version "7.0.1" + resolved "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.1.tgz#cb0d03e62e8762f3c80e52b025179de81899a823" + integrity sha512-/wTXAJwt0HzJ2IeE4kQXO+mBScfzyCkI0hMtkIaqyXd9zg76OpOfNQfHL9FlaxAV2RsNiOXZibVWloy8EexENg== + dependencies: + "@octokit/types" "^7.0.0" + is-plain-object "^5.0.0" + universal-user-agent "^6.0.0" + "@octokit/graphql@^4.5.8": version "4.8.0" resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz#664d9b11c0e12112cbf78e10f49a05959aa22cc3" @@ -5001,12 +5454,12 @@ universal-user-agent "^6.0.0" "@octokit/graphql@^5.0.0": - version "5.0.0" - resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.0.tgz#2cc6eb3bf8e0278656df1a7d0ca0d7591599e3b3" - integrity sha512-1ZZ8tX4lUEcLPvHagfIVu5S2xpHYXAmgN0+95eAOPoaVPzCfUXJtA5vASafcpWcO86ze0Pzn30TAx72aB2aguQ== + version "5.0.1" + resolved "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.1.tgz#a06982514ad131fb6fbb9da968653b2233fade9b" + integrity sha512-sxmnewSwAixkP1TrLdE6yRG53eEhHhDTYUykUwdV9x8f91WcbhunIHk9x1PZLALdBZKRPUO2HRcm4kezZ79HoA== dependencies: "@octokit/request" "^6.0.0" - "@octokit/types" "^6.0.3" + "@octokit/types" "^7.0.0" universal-user-agent "^6.0.0" "@octokit/oauth-app@^4.0.4", "@octokit/oauth-app@^4.0.6": @@ -5063,20 +5516,20 @@ resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz#b38d7fc3736d52a1e96b230c1ccd4a58a2f400a6" integrity sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA== -"@octokit/openapi-types@^12.4.0": - version "12.4.0" - resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.4.0.tgz#fd8bf5db72bd566c5ba2cb76754512a9ebe66e71" - integrity sha512-Npcb7Pv30b33U04jvcD7l75yLU0mxhuX2Xqrn51YyZ5WTkF04bpbxLaZ6GcaTqu03WZQHoO/Gbfp95NGRueDUA== +"@octokit/openapi-types@^12.11.0": + version "12.11.0" + resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz#da5638d64f2b919bca89ce6602d059f1b52d3ef0" + integrity sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ== -"@octokit/openapi-types@^12.7.0": - version "12.8.0" - resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.8.0.tgz#f4708cf948724d6e8f7d878cfd91584c1c5c0523" - integrity sha512-ydcKLs2KKcxlhpdWLzJxEBDEk/U5MUeqtqkXlrtAUXXFPs6vLl1PEGghFC/BbpleosB7iXs0Z4P2DGe7ZT5ZNg== +"@octokit/openapi-types@^13.0.0": + version "13.0.1" + resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-13.0.1.tgz#f655810f0dc0547b771526fea171acffbc7bd4a8" + integrity sha512-40U39YoFBhJhmkAg6gbJnh9U8aueJwCuiTW0mXY2pNl9/+E7dUxXiMPOrIUGT12XqLinroaXYA3FUiw3BMeNfg== "@octokit/openapi-types@^7.3.2": - version "7.3.2" - resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.3.2.tgz#065ce49b338043ec7f741316ce06afd4d459d944" - integrity sha512-oJhK/yhl9Gt430OrZOzAl2wJqR0No9445vmZ9Ey8GjUZUpwuu/vmEFP0TDhDXdpGDoxD6/EIFHJEcY8nHXpDTA== + version "7.4.0" + resolved "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-7.4.0.tgz#07631899dc32b72a532178e27235c541f3c359f1" + integrity sha512-V2qNML1knHjrjTJcIIvhYZSTkvtSAoQpNEX8y0ykTJI8vOQPqIh0y6Jf9EU6c/y+v0c9+LeC1acwLQh1xo96MA== "@octokit/plugin-enterprise-rest@^6.0.1": version "6.0.1" @@ -5097,6 +5550,13 @@ dependencies: "@octokit/types" "^6.39.0" +"@octokit/plugin-paginate-rest@^4.0.0": + version "4.0.0" + resolved "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-4.0.0.tgz#859a168262b657d46a8f1243ded66c87cee964b9" + integrity sha512-g4GJMt/7VDmIMMdQenN6bmsmRoZca1c7IxOdF2yMiMwQYrE2bmmypGQeQSD5rsaffsFMCUS7Br4pMVZamareYA== + dependencies: + "@octokit/types" "^7.0.0" + "@octokit/plugin-request-log@^1.0.2": version "1.0.2" resolved "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.2.tgz#394d59ec734cd2f122431fbaf05099861ece3c44" @@ -5116,11 +5576,11 @@ deprecation "^2.3.1" "@octokit/plugin-rest-endpoint-methods@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.0.0.tgz#e4a55d83ec5a00e6b4d7a780f4ec9009095bff6f" - integrity sha512-9LkEvZB3WDuayEI381O5A/eM3QQioBZrwymQp5CUCNz9UMP/yZAIqBjcPhVJJFA3IRkKO1EARo98OePt9i0rkQ== + version "6.3.0" + resolved "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-6.3.0.tgz#81549334ce020169b84bd4a7fa2577e9d725d829" + integrity sha512-qEu2wn6E7hqluZwIEUnDxWROvKjov3zMIAi4H4d7cmKWNMeBprEXZzJe8pE5eStUYC1ysGhD0B7L6IeG1Rfb+g== dependencies: - "@octokit/types" "^6.39.0" + "@octokit/types" "^7.0.0" deprecation "^2.3.1" "@octokit/plugin-retry@^3.0.9": @@ -5149,15 +5609,15 @@ once "^1.4.0" "@octokit/request-error@^3.0.0": - version "3.0.0" - resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.0.tgz#f527d178f115a3b62d76ce4804dd5bdbc0270a81" - integrity sha512-WBtpzm9lR8z4IHIMtOqr6XwfkGvMOOILNLxsWvDwtzm/n7f5AWuqJTXQXdDtOvPfTDrH4TPhEvW2qMlR4JFA2w== + version "3.0.1" + resolved "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.1.tgz#3fd747913c06ab2195e52004a521889dadb4b295" + integrity sha512-ym4Bp0HTP7F3VFssV88WD1ZyCIRoE8H35pXSKwLeMizcdZAYc/t6N9X9Yr9n6t3aG9IH75XDnZ6UeZph0vHMWQ== dependencies: - "@octokit/types" "^6.0.3" + "@octokit/types" "^7.0.0" deprecation "^2.0.0" once "^1.4.0" -"@octokit/request@^5.3.0", "@octokit/request@^5.4.12", "@octokit/request@^5.4.14", "@octokit/request@^5.6.0", "@octokit/request@^5.6.3": +"@octokit/request@^5.4.12", "@octokit/request@^5.4.14", "@octokit/request@^5.6.0", "@octokit/request@^5.6.3": version "5.6.3" resolved "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz#19a022515a5bba965ac06c9d1334514eb50c48b0" integrity sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A== @@ -5170,13 +5630,13 @@ universal-user-agent "^6.0.0" "@octokit/request@^6.0.0": - version "6.2.0" - resolved "https://registry.npmjs.org/@octokit/request/-/request-6.2.0.tgz#9c25606df84e6f2ccbcc2c58e1d35438e20b688b" - integrity sha512-7IAmHnaezZrgUqtRShMlByJK33MT9ZDnMRgZjnRrRV9a/jzzFwKGz0vxhFU6i7VMLraYcQ1qmcAOin37Kryq+Q== + version "6.2.1" + resolved "https://registry.npmjs.org/@octokit/request/-/request-6.2.1.tgz#3ceeb22dab09a29595d96594b6720fc14495cf4e" + integrity sha512-gYKRCia3cpajRzDSU+3pt1q2OcuC6PK8PmFIyxZDWCzRXRSIBH8jXjFJ8ZceoygBIm0KsEUg4x1+XcYBz7dHPQ== dependencies: "@octokit/endpoint" "^7.0.0" "@octokit/request-error" "^3.0.0" - "@octokit/types" "^6.16.1" + "@octokit/types" "^7.0.0" is-plain-object "^5.0.0" node-fetch "^2.6.7" universal-user-agent "^6.0.0" @@ -5192,29 +5652,36 @@ "@octokit/plugin-rest-endpoint-methods" "5.3.1" "@octokit/rest@^19.0.3": - version "19.0.3" - resolved "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.3.tgz#b9a4e8dc8d53e030d611c053153ee6045f080f02" - integrity sha512-5arkTsnnRT7/sbI4fqgSJ35KiFaN7zQm0uQiQtivNQLI8RQx8EHwJCajcTUwmaCMNDg7tdCvqAnc7uvHHPxrtQ== + version "19.0.4" + resolved "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.4.tgz#fd8bed1cefffa486e9ae46a9dc608ce81bcfcbdd" + integrity sha512-LwG668+6lE8zlSYOfwPj4FxWdv/qFXYBpv79TWIQEpBLKA9D/IMcWsF/U9RGpA3YqMVDiTxpgVpEW3zTFfPFTA== dependencies: "@octokit/core" "^4.0.0" - "@octokit/plugin-paginate-rest" "^3.0.0" + "@octokit/plugin-paginate-rest" "^4.0.0" "@octokit/plugin-request-log" "^1.0.4" "@octokit/plugin-rest-endpoint-methods" "^6.0.0" -"@octokit/types@^5.0.0", "@octokit/types@^5.0.1": +"@octokit/types@^5.0.1": version "5.5.0" resolved "https://registry.npmjs.org/@octokit/types/-/types-5.5.0.tgz#e5f06e8db21246ca102aa28444cdb13ae17a139b" integrity sha512-UZ1pErDue6bZNjYOotCNveTXArOMZQFG6hKJfOnGnulVCMcVVi7YIIuuR4WfBhjo7zgpmzn/BkPDnUXtNx+PcQ== dependencies: "@types/node" ">= 8" -"@octokit/types@^6.0.0", "@octokit/types@^6.0.1", "@octokit/types@^6.0.3", "@octokit/types@^6.10.0", "@octokit/types@^6.12.2", "@octokit/types@^6.14.2", "@octokit/types@^6.16.1", "@octokit/types@^6.16.2", "@octokit/types@^6.8.2": +"@octokit/types@^6.0.0", "@octokit/types@^6.0.1", "@octokit/types@^6.10.0", "@octokit/types@^6.12.2", "@octokit/types@^6.14.2", "@octokit/types@^6.16.2", "@octokit/types@^6.8.2": version "6.16.4" resolved "https://registry.npmjs.org/@octokit/types/-/types-6.16.4.tgz#d24f5e1bacd2fe96d61854b5bda0e88cf8288dfe" integrity sha512-UxhWCdSzloULfUyamfOg4dJxV9B+XjgrIZscI0VCbp4eNrjmorGEw+4qdwcpTsu6DIrm9tQsFQS2pK5QkqQ04A== dependencies: "@octokit/openapi-types" "^7.3.2" +"@octokit/types@^6.0.3", "@octokit/types@^6.16.1", "@octokit/types@^6.39.0": + version "6.41.0" + resolved "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz#e58ef78d78596d2fb7df9c6259802464b5f84a04" + integrity sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg== + dependencies: + "@octokit/openapi-types" "^12.11.0" + "@octokit/types@^6.27.1": version "6.34.0" resolved "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz#c6021333334d1ecfb5d370a8798162ddf1ae8218" @@ -5222,38 +5689,31 @@ dependencies: "@octokit/openapi-types" "^11.2.0" -"@octokit/types@^6.35.0": - version "6.37.0" - resolved "https://registry.npmjs.org/@octokit/types/-/types-6.37.0.tgz#32eb78edb34cf5cea4ba5753ab8db75b776d617a" - integrity sha512-BXWQhFKRkjX4dVW5L2oYa0hzWOAqsEsujXsQLSdepPoDZfYdubrD1KDGpyNldGXtR8QM/WezDcxcIN1UKJMGPA== +"@octokit/types@^7.0.0": + version "7.0.0" + resolved "https://registry.npmjs.org/@octokit/types/-/types-7.0.0.tgz#3ecee92edff53a93ecd75d6b9d6620574d2048ca" + integrity sha512-8uSDc66p6+wADn6lh6lA7I3ZTIapn7F/dfpsiDztVjEr6kkyKR3qPqa4lgEX92O/8iJoDeGcscKRXGAjCSR/zg== dependencies: - "@octokit/openapi-types" "^12.4.0" - -"@octokit/types@^6.39.0": - version "6.39.0" - resolved "https://registry.npmjs.org/@octokit/types/-/types-6.39.0.tgz#46ce28ca59a3d4bac0e487015949008302e78eee" - integrity sha512-Mq4N9sOAYCitTsBtDdRVrBE80lIrMBhL9Jbrw0d+j96BAzlq4V+GLHFJbHokEsVvO/9tQupQdoFdgVYhD2C8UQ== - dependencies: - "@octokit/openapi-types" "^12.7.0" + "@octokit/openapi-types" "^13.0.0" "@octokit/webhooks-methods@^3.0.0": version "3.0.0" resolved "https://registry.npmjs.org/@octokit/webhooks-methods/-/webhooks-methods-3.0.0.tgz#4f4443605233f46abc5f85a857ba105095aa1181" integrity sha512-FAIyAchH9JUKXugKMC17ERAXM/56vVJekwXOON46pmUDYfU7uXB4cFY8yc8nYr5ABqVI7KjRKfFt3mZF7OcyUA== -"@octokit/webhooks-types@6.2.3": - version "6.2.3" - resolved "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-6.2.3.tgz#9ef209ecf542f1c4c4e16bd00aea0638889e116d" - integrity sha512-m2J23W6QZeB7KOMHSgTZG8F0mXqqWlWrVzn41Zj4l2umHb6H3Z+rqFsryTNBTZuUiO7YFOFqYaTtlSGHC5CgUg== +"@octokit/webhooks-types@6.3.6": + version "6.3.6" + resolved "https://registry.npmjs.org/@octokit/webhooks-types/-/webhooks-types-6.3.6.tgz#b211e42386463175ebc652c86d5c7433675986fc" + integrity sha512-x6yBtWobk20OhOiJ4VWsH3iJ/30IG+VoDWSgS4Tiyidi2KOiBS3bL+AJrNuq4OyNuWOM/FbHQTp6KEZs1oPD/g== "@octokit/webhooks@^10.0.0": - version "10.0.8" - resolved "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-10.0.8.tgz#e8fae861432411d80cade44e7d3725ba8613a4cf" - integrity sha512-B6TfNTPDf8y5WqzlT5jmeYaYSf6oT7NhkelcetaDT7PP9btu1iaIKWZG+1DFRm1CBQE9HIHdh9rR65qq64m/5g== + version "10.1.5" + resolved "https://registry.npmjs.org/@octokit/webhooks/-/webhooks-10.1.5.tgz#ba79b49ef0047a3cae7885387c5f20d4b341cd41" + integrity sha512-sQkxM6l9HdG1vsHFj2T/o8SnCPDDxovcs0rsSd4UR5jJFNPCPIBRmFNVHfM37nncLKuTwIpmMeePphNf1k6Waw== dependencies: "@octokit/request-error" "^3.0.0" "@octokit/webhooks-methods" "^3.0.0" - "@octokit/webhooks-types" "6.2.3" + "@octokit/webhooks-types" "6.3.6" aggregate-error "^3.1.0" "@open-draft/until@^1.0.3": @@ -5305,6 +5765,33 @@ resolved "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.4.tgz#a167e46c10d05a07ab299fc518793b0cff8f6924" integrity sha512-BuJuXRSJNQ3QoKA6GWWDyuLpOUck+9hAXNMCnrloc1aWVoy6Xq6t9PUV08aBZ4Lutqq2LEHM486bpZqoViScog== +"@peculiar/asn1-schema@^2.1.6": + version "2.2.0" + resolved "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.2.0.tgz#d8a54527685c8dee518e6448137349444310ad64" + integrity sha512-1ENEJNY7Lwlua/1wvzpYP194WtjQBfFxvde2FlzfBFh/ln6wvChrtxlORhbKEnYswzn6fOC4c7HdC5izLPMTJg== + dependencies: + asn1js "^3.0.5" + pvtsutils "^1.3.2" + tslib "^2.4.0" + +"@peculiar/json-schema@^1.1.12": + version "1.1.12" + resolved "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz#fe61e85259e3b5ba5ad566cb62ca75b3d3cd5339" + integrity sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w== + dependencies: + tslib "^2.0.0" + +"@peculiar/webcrypto@^1.4.0": + version "1.4.0" + resolved "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.0.tgz#f941bd95285a0f8a3d2af39ccda5197b80cd32bf" + integrity sha512-U58N44b2m3OuTgpmKgf0LPDOmP3bhwNz01vAnj1mBwxBASRhptWYK+M3zG+HBkDqGQM+bFsoIihTW8MdmPXEqg== + dependencies: + "@peculiar/asn1-schema" "^2.1.6" + "@peculiar/json-schema" "^1.1.12" + pvtsutils "^1.3.2" + tslib "^2.4.0" + webcrypto-core "^1.7.4" + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" resolved "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" @@ -5358,24 +5845,17 @@ resolved "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= -"@react-hookz/deep-equal@^1.0.2": - version "1.0.2" - resolved "https://registry.npmjs.org/@react-hookz/deep-equal/-/deep-equal-1.0.2.tgz#4e8bdeda027379dcf8b62a42e5f75f0351b11b35" - integrity sha512-cM5kPFb6EFH5q52WzRxfRX9+8g5kq78McWOYs6e1seo+nK6NpfLupT5uOCIJp37jU8ayd4Su8ni3HRFTN2C2kg== - -"@react-hookz/web@^14.0.0": - version "14.7.1" - resolved "https://registry.npmjs.org/@react-hookz/web/-/web-14.7.1.tgz#5e39e6fc21331cc4ae95f36e8135ad763e6c29fb" - integrity sha512-kU1CccZDXvQ9G4vcCCpX3mDQqYKkuLXGFOtPMgmbZ9KrvkEduMRH4JqSVXp1nI/bGI1GJ0KAWm4UEb1x5eDGAg== - dependencies: - "@react-hookz/deep-equal" "^1.0.2" +"@react-hookz/deep-equal@^1.0.3": + version "1.0.3" + resolved "https://registry.npmjs.org/@react-hookz/deep-equal/-/deep-equal-1.0.3.tgz#e044bca38c1612ea8c1596ef858ef7cfea49dd7a" + integrity sha512-lGZR5l3YRjzeIOHtJhiq96vQKrsq+9lsCyv+0fROMQeSNWtLLzX3R+psHNi6nsoP3XEhspiZ92nsiPmdNo8ztQ== "@react-hookz/web@^15.0.0": - version "15.0.1" - resolved "https://registry.npmjs.org/@react-hookz/web/-/web-15.0.1.tgz#a6e5460dd16e54ccc0b899e1eed4ae29e871060f" - integrity sha512-nvVLUsDFv3fpZcINoy3I4MeaX8+yoKU21m2Ey2g0VAVqOMp+0GBBC6OHkzT2lRa2fiPIVuJwlmboSKQt7segfQ== + version "15.1.0" + resolved "https://registry.npmjs.org/@react-hookz/web/-/web-15.1.0.tgz#62f7cedb98f345a1cdc7437673ea93dfb4d753d1" + integrity sha512-AsmqeZDg22JnpQS1hGIjLbue4LPmcsgyoPzgmKt6WDeqIUWFL20cgowiGBMFNLvL5Cc9XdusVY720S+CpLyT4Q== dependencies: - "@react-hookz/deep-equal" "^1.0.2" + "@react-hookz/deep-equal" "^1.0.3" "@rjsf/core@^3.2.1": version "3.2.1" @@ -5398,12 +5878,12 @@ integrity sha512-8UiDeDbjCImFSfOegGu13otQ7OdP9FOYpcLjeouppnhs+MPeIEAtYS+jCcBKmi3reyTagC15/KVSRhde1wS1vg== "@roadiehq/backstage-plugin-buildkite@^2.0.0": - version "2.0.4" - resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-buildkite/-/backstage-plugin-buildkite-2.0.4.tgz#cd72fd35a9f8b6bb1c2ccd3c13d2aece2ecaf86e" - integrity sha512-bOrqKO9MmRB5jgue+S8WEmJk83h6g4EdGp2qmirVODQddL03gtFNgMTauQkKAV7T8N+C948xDcgdL3pjvLYJdA== + version "2.0.7" + resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-buildkite/-/backstage-plugin-buildkite-2.0.7.tgz#fdd6b3d3c0eb2be09b35b38b207d6a0873147764" + integrity sha512-TTv6S2+ByNG2BFtonwDQ/RiMpbTyQxkSFNdw1ZWQZyiaeMYRdIxlTKsZ8BzvmcGW+Ez6z7zEFT6x2T22GdXvqA== dependencies: "@backstage/catalog-model" "^1.0.0" - "@backstage/core-components" "^0.9.0" + "@backstage/core-components" "^0.11.0" "@backstage/core-plugin-api" "^1.0.0" "@backstage/plugin-catalog-react" "^1.0.0" "@backstage/theme" "^0.2.6" @@ -5417,12 +5897,12 @@ react-use "^17.2.4" "@roadiehq/backstage-plugin-github-insights@^2.0.0": - version "2.0.1" - resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-github-insights/-/backstage-plugin-github-insights-2.0.1.tgz#b0cccdd5cfe1c94055ad372087a1daba9ec72bb4" - integrity sha512-Kq3JdzSIpLV0Ka6GqX7Ok2QW/s6w18l0Kyec+OtQ+/1dz8AeG7UoYwUtBI/+sTd+gveTHAonwi9xINYbcIvQhQ== + version "2.0.4" + resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-github-insights/-/backstage-plugin-github-insights-2.0.4.tgz#4b90f6081795340922d47d3a6abfe6fa877c0746" + integrity sha512-e+WCgWycfvqwn3cNJ37qD0YOtrinUWhFoQGh7spEsNYba9RUN/dSkUcMP1sSWcnHgWOJKtx1s//YbxeeUc4uXw== dependencies: "@backstage/catalog-model" "^1.0.0" - "@backstage/core-components" "^0.9.0" + "@backstage/core-components" "^0.11.0" "@backstage/core-plugin-api" "^1.0.0" "@backstage/integration-react" "^1.0.0" "@backstage/plugin-catalog-react" "^1.0.0" @@ -5431,7 +5911,6 @@ "@material-ui/core" "^4.11.0" "@material-ui/icons" "^4.9.1" "@material-ui/lab" "4.0.0-alpha.45" - "@octokit/request-error" "^2.1.0" "@octokit/rest" "^18.5.3" "@octokit/types" "^6.14.2" history "^5.0.0" @@ -5441,12 +5920,12 @@ zustand "3.6.9" "@roadiehq/backstage-plugin-github-pull-requests@^2.0.0": - version "2.2.1" - resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-github-pull-requests/-/backstage-plugin-github-pull-requests-2.2.1.tgz#a50ca71c70fb16283bd65427688c3c5e9425dec7" - integrity sha512-oMLe1ew8hee9LfV5Pdw25sV1XdoMxpq/ZKZWWtZTS0iCudgWleslkdj20preF8FPuHQjkr1xAtnDdnMWvejtxQ== + version "2.2.5" + resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-github-pull-requests/-/backstage-plugin-github-pull-requests-2.2.5.tgz#280fb55f6c2378cc8eb32e2acf25a0522a2ef110" + integrity sha512-8zK4uw5FhqfOwUF0oOp2cXsh+HQzsmmynN5WsLmir6v5CX6p8LPEZbb9aBDD2Gx2pC/s3776xQO95kCbizeUxg== dependencies: "@backstage/catalog-model" "^1.0.0" - "@backstage/core-components" "^0.9.0" + "@backstage/core-components" "^0.10.0" "@backstage/core-plugin-api" "^1.0.0" "@backstage/plugin-catalog-react" "^1.0.0" "@backstage/plugin-home" "^0.4.19" @@ -5465,12 +5944,12 @@ react-use "^17.2.4" "@roadiehq/backstage-plugin-travis-ci@^2.0.0": - version "2.0.1" - resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-travis-ci/-/backstage-plugin-travis-ci-2.0.1.tgz#0d706d3a31b123cd2e76b6d7fd849ae8cb97e786" - integrity sha512-Qay8Ad+heMEyW5QPi2I4C7ky3NUYhgE7FF+pV77ES21zyytCcTHQIkYHJd0FrR6WpedtNSegfcRj61VSZfbRKA== + version "2.0.4" + resolved "https://registry.npmjs.org/@roadiehq/backstage-plugin-travis-ci/-/backstage-plugin-travis-ci-2.0.4.tgz#be6504edfe58e4ae7156397589db7e7c644927bc" + integrity sha512-SpoQf2fSvN3OQKSeZaLBLZSk8+R9kyXONNZMyhLJj2cq/kQwvYeBn/PuURCV4bMxBg/zt21CUnfmAMXDeG1guw== dependencies: "@backstage/catalog-model" "^1.0.0" - "@backstage/core-components" "^0.9.0" + "@backstage/core-components" "^0.11.0" "@backstage/core-plugin-api" "^1.0.0" "@backstage/plugin-catalog-react" "^1.0.0" "@backstage/theme" "^0.2.9" @@ -5486,9 +5965,9 @@ react-use "^17.2.4" "@rollup/plugin-commonjs@^22.0.0": - version "22.0.1" - resolved "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.1.tgz#f7cb777d20de3eeeaf994f39080115c336bef810" - integrity sha512-dGfEZvdjDHObBiP5IvwTKMVeq/tBZGMBHZFMdIV1ClMM/YoWS34xrHFGfag9SN2ZtMgNZRFruqvxZQEa70O6nQ== + version "22.0.2" + resolved "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.2.tgz#ee8ca8415cda30d383b4096aad5222435b4b69b6" + integrity sha512-//NdP6iIwPbMTcazYsiBMbJW7gfmpHom33u1beiIoHDEM0Q9clvtQB1T0efvMqHeKsGohiHo97BCPCkBXdscwg== dependencies: "@rollup/pluginutils" "^3.1.0" commondir "^1.0.1" @@ -5543,6 +6022,14 @@ estree-walker "^2.0.1" picomatch "^2.2.2" +"@rollup/pluginutils@^4.2.1": + version "4.2.1" + resolved "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" + integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== + dependencies: + estree-walker "^2.0.1" + picomatch "^2.2.2" + "@rushstack/node-core-library@3.45.4": version "3.45.4" resolved "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.45.4.tgz#a5e1246c462940d16a5acc667c1ffe460b514087" @@ -5676,124 +6163,124 @@ dependencies: loader-utils "^1.1.0" -"@svgr/babel-plugin-add-jsx-attribute@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.0.0.tgz#bd6d1ff32a31b82b601e73672a789cc41e84fe18" - integrity sha512-MdPdhdWLtQsjd29Wa4pABdhWbaRMACdM1h31BY+c6FghTZqNGT7pEYdBoaGeKtdTOBC/XNFQaKVj+r/Ei2ryWA== +"@svgr/babel-plugin-add-jsx-attribute@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.3.1.tgz#b9a5d84902be75a05ede92e70b338d28ab63fa74" + integrity sha512-jDBKArXYO1u0B1dmd2Nf8Oy6aTF5vLDfLoO9Oon/GLkqZ/NiggYWZA+a2HpUMH4ITwNqS3z43k8LWApB8S583w== -"@svgr/babel-plugin-remove-jsx-attribute@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-6.0.0.tgz#58654908beebfa069681a83332544b17e5237e89" - integrity sha512-aVdtfx9jlaaxc3unA6l+M9YRnKIZjOhQPthLKqmTXC8UVkBLDRGwPKo+r8n3VZN8B34+yVajzPTZ+ptTSuZZCw== +"@svgr/babel-plugin-remove-jsx-attribute@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-6.3.1.tgz#4877995452efc997b36777abe1fde9705ef78e8b" + integrity sha512-dQzyJ4prwjcFd929T43Z8vSYiTlTu8eafV40Z2gO7zy/SV5GT+ogxRJRBIKWomPBOiaVXFg3jY4S5hyEN3IBjQ== -"@svgr/babel-plugin-remove-jsx-empty-expression@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-6.0.0.tgz#d06dd6e8a8f603f92f9979bb9990a1f85a4f57ba" - integrity sha512-Ccj42ApsePD451AZJJf1QzTD1B/BOU392URJTeXFxSK709i0KUsGtbwyiqsKu7vsYxpTM0IA5clAKDyf9RCZyA== +"@svgr/babel-plugin-remove-jsx-empty-expression@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-6.3.1.tgz#2d67a0e92904c9be149a5b22d3a3797ce4d7b514" + integrity sha512-HBOUc1XwSU67fU26V5Sfb8MQsT0HvUyxru7d0oBJ4rA2s4HW3PhyAPC7fV/mdsSGpAvOdd8Wpvkjsr0fWPUO7A== -"@svgr/babel-plugin-replace-jsx-attribute-value@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.0.0.tgz#0b85837577b02c31c09c758a12932820f5245cee" - integrity sha512-88V26WGyt1Sfd1emBYmBJRWMmgarrExpKNVmI9vVozha4kqs6FzQJ/Kp5+EYli1apgX44518/0+t9+NU36lThQ== +"@svgr/babel-plugin-replace-jsx-attribute-value@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.3.1.tgz#306f5247139c53af70d1778f2719647c747998ee" + integrity sha512-C12e6aN4BXAolRrI601gPn5MDFCRHO7C4TM8Kks+rDtl8eEq+NN1sak0eAzJu363x3TmHXdZn7+Efd2nr9I5dA== -"@svgr/babel-plugin-svg-dynamic-title@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.0.0.tgz#28236ec26f7ab9d486a487d36ae52d58ba15676f" - integrity sha512-F7YXNLfGze+xv0KMQxrl2vkNbI9kzT9oDK55/kUuymh1ACyXkMV+VZWX1zEhSTfEKh7VkHVZGmVtHg8eTZ6PRg== +"@svgr/babel-plugin-svg-dynamic-title@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.3.1.tgz#6ce26d34cbc93eb81737ef528528907c292e7aa2" + integrity sha512-6NU55Mmh3M5u2CfCCt6TX29/pPneutrkJnnDCHbKZnjukZmmgUAZLtZ2g6ZoSPdarowaQmAiBRgAHqHmG0vuqA== -"@svgr/babel-plugin-svg-em-dimensions@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.0.0.tgz#40267c5dea1b43c4f83a0eb6169e08b43d8bafce" - integrity sha512-+rghFXxdIqJNLQK08kwPBD3Z22/0b2tEZ9lKiL/yTfuyj1wW8HUXu4bo/XkogATIYuXSghVQOOCwURXzHGKyZA== +"@svgr/babel-plugin-svg-em-dimensions@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.3.1.tgz#5ade2a724b290873c30529d1d8cd23523856287a" + integrity sha512-HV1NGHYTTe1vCNKlBgq/gKuCSfaRlKcHIADn7P8w8U3Zvujdw1rmusutghJ1pZJV7pDt3Gt8ws+SVrqHnBO/Qw== -"@svgr/babel-plugin-transform-react-native-svg@^6.0.0": - version "6.0.0" - resolved "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.0.0.tgz#eb688d0a5f539e34d268d8a516e81f5d7fede7c9" - integrity sha512-VaphyHZ+xIKv5v0K0HCzyfAaLhPGJXSk2HkpYfXIOKb7DjLBv0soHDxNv6X0vr2titsxE7klb++u7iOf7TSrFQ== +"@svgr/babel-plugin-transform-react-native-svg@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.3.1.tgz#d654f509d692c3a09dfb475757a44bd9f6ad7ddf" + integrity sha512-2wZhSHvTolFNeKDAN/ZmIeSz2O9JSw72XD+o2bNp2QAaWqa8KGpn5Yk5WHso6xqfSAiRzAE+GXlsrBO4UP9LLw== -"@svgr/babel-plugin-transform-svg-component@^6.2.0": - version "6.2.0" - resolved "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.2.0.tgz#7ba61d9fc1fb42b0ba1a04e4630019fa7e993c4f" - integrity sha512-bhYIpsORb++wpsp91fymbFkf09Z/YEKR0DnFjxvN+8JHeCUD2unnh18jIMKnDJTWtvpTaGYPXELVe4OOzFI0xg== +"@svgr/babel-plugin-transform-svg-component@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.3.1.tgz#21a285dbffdce9567c437ebf0d081bf9210807e6" + integrity sha512-cZ8Tr6ZAWNUFfDeCKn/pGi976iWSkS8ijmEYKosP+6ktdZ7lW9HVLHojyusPw3w0j8PI4VBeWAXAmi/2G7owxw== -"@svgr/babel-preset@^6.2.0": - version "6.2.0" - resolved "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.2.0.tgz#1d3ad8c7664253a4be8e4a0f0e6872f30d8af627" - integrity sha512-4WQNY0J71JIaL03DRn0vLiz87JXx0b9dYm2aA8XHlQJQoixMl4r/soYHm8dsaJZ3jWtkCiOYy48dp9izvXhDkQ== +"@svgr/babel-preset@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-6.3.1.tgz#8bd1ead79637d395e9362b01dd37cfd59702e152" + integrity sha512-tQtWtzuMMQ3opH7je+MpwfuRA1Hf3cKdSgTtAYwOBDfmhabP7rcTfBi3E7V3MuwJNy/Y02/7/RutvwS1W4Qv9g== dependencies: - "@svgr/babel-plugin-add-jsx-attribute" "^6.0.0" - "@svgr/babel-plugin-remove-jsx-attribute" "^6.0.0" - "@svgr/babel-plugin-remove-jsx-empty-expression" "^6.0.0" - "@svgr/babel-plugin-replace-jsx-attribute-value" "^6.0.0" - "@svgr/babel-plugin-svg-dynamic-title" "^6.0.0" - "@svgr/babel-plugin-svg-em-dimensions" "^6.0.0" - "@svgr/babel-plugin-transform-react-native-svg" "^6.0.0" - "@svgr/babel-plugin-transform-svg-component" "^6.2.0" + "@svgr/babel-plugin-add-jsx-attribute" "^6.3.1" + "@svgr/babel-plugin-remove-jsx-attribute" "^6.3.1" + "@svgr/babel-plugin-remove-jsx-empty-expression" "^6.3.1" + "@svgr/babel-plugin-replace-jsx-attribute-value" "^6.3.1" + "@svgr/babel-plugin-svg-dynamic-title" "^6.3.1" + "@svgr/babel-plugin-svg-em-dimensions" "^6.3.1" + "@svgr/babel-plugin-transform-react-native-svg" "^6.3.1" + "@svgr/babel-plugin-transform-svg-component" "^6.3.1" -"@svgr/core@^6.2.1": - version "6.2.1" - resolved "https://registry.npmjs.org/@svgr/core/-/core-6.2.1.tgz#195de807a9f27f9e0e0d678e01084b05c54fdf61" - integrity sha512-NWufjGI2WUyrg46mKuySfviEJ6IxHUOm/8a3Ph38VCWSp+83HBraCQrpEM3F3dB6LBs5x8OElS8h3C0oOJaJAA== +"@svgr/core@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/core/-/core-6.3.1.tgz#752adf49d8d5473b15d76ca741961de093f715bd" + integrity sha512-Sm3/7OdXbQreemf9aO25keerZSbnKMpGEfmH90EyYpj1e8wMD4TuwJIb3THDSgRMWk1kYJfSRulELBy4gVgZUA== dependencies: - "@svgr/plugin-jsx" "^6.2.1" + "@svgr/plugin-jsx" "^6.3.1" camelcase "^6.2.0" cosmiconfig "^7.0.1" -"@svgr/hast-util-to-babel-ast@^6.2.1": - version "6.2.1" - resolved "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.2.1.tgz#ae065567b74cbe745afae617053adf9a764bea25" - integrity sha512-pt7MMkQFDlWJVy9ULJ1h+hZBDGFfSCwlBNW1HkLnVi7jUhyEXUaGYWi1x6bM2IXuAR9l265khBT4Av4lPmaNLQ== +"@svgr/hast-util-to-babel-ast@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.3.1.tgz#59614e24d2a4a28010e02089213b3448d905769d" + integrity sha512-NgyCbiTQIwe3wHe/VWOUjyxmpUmsrBjdoIxKpXt3Nqc3TN30BpJG22OxBvVzsAh9jqep0w0/h8Ywvdk3D9niNQ== dependencies: - "@babel/types" "^7.15.6" - entities "^3.0.1" + "@babel/types" "^7.18.4" + entities "^4.3.0" -"@svgr/plugin-jsx@6.2.x", "@svgr/plugin-jsx@^6.2.1": - version "6.2.1" - resolved "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.2.1.tgz#5668f1d2aa18c2f1bb7a1fc9f682d3f9aed263bd" - integrity sha512-u+MpjTsLaKo6r3pHeeSVsh9hmGRag2L7VzApWIaS8imNguqoUwDq/u6U/NDmYs/KAsrmtBjOEaAAPbwNGXXp1g== +"@svgr/plugin-jsx@6.3.x", "@svgr/plugin-jsx@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-6.3.1.tgz#de7b2de824296b836d6b874d498377896e367f50" + integrity sha512-r9+0mYG3hD4nNtUgsTXWGYJomv/bNd7kC16zvsM70I/bGeoCi/3lhTmYqeN6ChWX317OtQCSZZbH4wq9WwoXbw== dependencies: - "@babel/core" "^7.15.5" - "@svgr/babel-preset" "^6.2.0" - "@svgr/hast-util-to-babel-ast" "^6.2.1" - svg-parser "^2.0.2" + "@babel/core" "^7.18.5" + "@svgr/babel-preset" "^6.3.1" + "@svgr/hast-util-to-babel-ast" "^6.3.1" + svg-parser "^2.0.4" -"@svgr/plugin-svgo@6.2.x", "@svgr/plugin-svgo@^6.2.0": - version "6.2.0" - resolved "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.2.0.tgz#4cbe6a33ccccdcae4e3b63ded64cc1cbe1faf48c" - integrity sha512-oDdMQONKOJEbuKwuy4Np6VdV6qoaLLvoY86hjvQEgU82Vx1MSWRyYms6Sl0f+NtqxLI/rDVufATbP/ev996k3Q== +"@svgr/plugin-svgo@6.3.x", "@svgr/plugin-svgo@^6.3.1": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-6.3.1.tgz#3c1ff2efaed10e5c5d35a6cae7bacaedc18b5d4a" + integrity sha512-yJIjTDKPYqzFVjmsbH5EdIwEsmKxjxdXSGJVLeUgwZOZPAkNQmD1v7LDbOdOKbR44FG8465Du+zWPdbYGnbMbw== dependencies: cosmiconfig "^7.0.1" deepmerge "^4.2.2" - svgo "^2.5.0" + svgo "^2.8.0" -"@svgr/rollup@6.2.x": - version "6.2.1" - resolved "https://registry.npmjs.org/@svgr/rollup/-/rollup-6.2.1.tgz#23ac3173d2bd85842ca8858d3435332af1f064ab" - integrity sha512-5X6aMiGL1F5g0TubLY41GJ/Qf0Kz2xtbF37UbRJEHe2Z9CMlGl9Z3fQ8e28vmHrTptmymNRoHssgQ2Ejb1DARQ== +"@svgr/rollup@6.3.x": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/rollup/-/rollup-6.3.1.tgz#cf59c39f1f145383dfdeea7068ec18149360668e" + integrity sha512-TXcRT7pwsNU30bXxgooGAZQIXmPy7fxUnN/v5cuCpLiondRtKiV321kh/S/qhcQ6gSs6DvJmNDpbiqPZF66usw== dependencies: - "@babel/core" "^7.15.5" - "@babel/plugin-transform-react-constant-elements" "^7.14.5" - "@babel/preset-env" "^7.15.6" - "@babel/preset-react" "^7.14.5" - "@babel/preset-typescript" "^7.16.0" - "@svgr/core" "^6.2.1" - "@svgr/plugin-jsx" "^6.2.1" - "@svgr/plugin-svgo" "^6.2.0" - rollup-pluginutils "^2.8.2" + "@babel/core" "^7.18.5" + "@babel/plugin-transform-react-constant-elements" "^7.17.12" + "@babel/preset-env" "^7.18.2" + "@babel/preset-react" "^7.17.12" + "@babel/preset-typescript" "^7.17.12" + "@rollup/pluginutils" "^4.2.1" + "@svgr/core" "^6.3.1" + "@svgr/plugin-jsx" "^6.3.1" + "@svgr/plugin-svgo" "^6.3.1" -"@svgr/webpack@6.2.x": - version "6.2.1" - resolved "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.2.1.tgz#ef5d51c1b6be4e7537fb9f76b3f2b2e22b63c58d" - integrity sha512-h09ngMNd13hnePwgXa+Y5CgOjzlCvfWLHg+MBnydEedAnuLRzUHUJmGS3o2OsrhxTOOqEsPOFt5v/f6C5Qulcw== +"@svgr/webpack@6.3.x": + version "6.3.1" + resolved "https://registry.npmjs.org/@svgr/webpack/-/webpack-6.3.1.tgz#001d03236ebb03bf47c0a4b92d5423e05095ebe6" + integrity sha512-eODxwIUShLxSMaRjzJtrj9wg89D75JLczvWg9SaB5W+OtVTkiC1vdGd8+t+pf5fTlBOy4RRXAq7x1E3DUl3D0A== dependencies: - "@babel/core" "^7.15.5" - "@babel/plugin-transform-react-constant-elements" "^7.14.5" - "@babel/preset-env" "^7.15.6" - "@babel/preset-react" "^7.14.5" - "@babel/preset-typescript" "^7.15.0" - "@svgr/core" "^6.2.1" - "@svgr/plugin-jsx" "^6.2.1" - "@svgr/plugin-svgo" "^6.2.0" + "@babel/core" "^7.18.5" + "@babel/plugin-transform-react-constant-elements" "^7.17.12" + "@babel/preset-env" "^7.18.2" + "@babel/preset-react" "^7.17.12" + "@babel/preset-typescript" "^7.17.12" + "@svgr/core" "^6.3.1" + "@svgr/plugin-jsx" "^6.3.1" + "@svgr/plugin-svgo" "^6.3.1" "@szmarczak/http-timer@^4.0.5": version "4.0.5" @@ -5825,15 +6312,15 @@ pretty-format "^27.0.2" "@testing-library/jest-dom@^5.10.1", "@testing-library/jest-dom@^5.16.4": - version "5.16.4" - resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd" - integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA== + version "5.16.5" + resolved "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz#3912846af19a29b2dbf32a6ae9c31ef52580074e" + integrity sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA== dependencies: + "@adobe/css-tools" "^4.0.1" "@babel/runtime" "^7.9.2" "@types/testing-library__jest-dom" "^5.9.1" aria-query "^5.0.0" chalk "^3.0.0" - css "^3.0.0" css.escape "^1.5.1" dom-accessibility-api "^0.5.6" lodash "^4.17.15" @@ -5857,9 +6344,9 @@ "@types/react-dom" "<18.0.0" "@testing-library/user-event@^14.0.0": - version "14.2.3" - resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.2.3.tgz#7731a9c2d4148f2f9bb53d718c56dc9e6afe5b3e" - integrity sha512-07Ly+NsFDTvjNdvl5bLBA5oHeGIIHCKc7CniGuKnHrjvqcTPVqPEo4z6a8iYydZ0WvDA6ZA0fnhYrqCLbsm0+A== + version "14.3.0" + resolved "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.3.0.tgz#0a6750b94b40e4739706d41e8efc2ccf64d2aad9" + integrity sha512-P02xtBBa8yMaLhK8CzJCIns8rqwnF6FxhR9zs810flHOBXUYCFjLd8Io1rQrAkQRWEmW2PGdZIEdMxf/KLsqFA== "@tokenizer/token@^0.3.0": version "0.3.0" @@ -6211,14 +6698,14 @@ "@types/d3-time" "^2" "@types/d3-selection@*", "@types/d3-selection@^3.0.1": - version "3.0.2" - resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.2.tgz#23e48a285b24063630bbe312cc0cfe2276de4a59" - integrity sha512-d29EDd0iUBrRoKhPndhDY6U/PYxOWqgIZwKTooy2UkBfU7TNZNpRho0yLWPxlatQrFWk2mnTu71IZQ4+LRgKlQ== + version "3.0.3" + resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.3.tgz#57be7da68e7d9c9b29efefd8ea5a9ef1171e42ba" + integrity sha512-Mw5cf6nlW1MlefpD9zrshZ+DAWL4IQ5LnWfRheW6xwsdaWOb6IRRu2H7XPAQcyXEx1D7XQWgdoKR83ui1/HlEA== "@types/d3-shape@^1": - version "1.3.5" - resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.3.5.tgz#c0164c1be1429473016f855871d487f806c4e968" - integrity sha512-aPEax03owTAKynoK8ZkmkZEDZvvT4Y5pWgii4Jp4oQt0gH45j6siDl9gNDVC5kl64XHN2goN9jbYoHK88tFAcA== + version "1.3.8" + resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-1.3.8.tgz#c3c15ec7436b4ce24e38de517586850f1fea8e89" + integrity sha512-gqfnMz6Fd5H6GOLYixOZP/xlrMtJms9BaS+6oWxTKHNqPGZ93BkWWupQSCYm6YHqx6h9wjRupuJb90bun6ZaYg== dependencies: "@types/d3-path" "^1" @@ -6333,7 +6820,7 @@ resolved "https://registry.npmjs.org/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== -"@types/express-serve-static-core@*", "@types/express-serve-static-core@4.17.29", "@types/express-serve-static-core@^4.17.18", "@types/express-serve-static-core@^4.17.5": +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18", "@types/express-serve-static-core@^4.17.5": version "4.17.29" resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.29.tgz#2a1795ea8e9e9c91b4a4bbe475034b20c1ec711c" integrity sha512-uMd++6dMKS32EOuw1Uli3e3BPgdLIXmezcfHv7N4c1s3gkhikBplORPpMq3fuWkxncZN1reb16d5n8yhQ80x7Q== @@ -6342,6 +6829,15 @@ "@types/qs" "*" "@types/range-parser" "*" +"@types/express-serve-static-core@4.17.30": + version "4.17.30" + resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz#0f2f99617fa8f9696170c46152ccf7500b34ac04" + integrity sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/express-session@^1.17.2": version "1.17.5" resolved "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.5.tgz#13f48852b4aa60ff595835faeb4b4dda0ba0866e" @@ -6463,12 +6959,11 @@ integrity sha512-K3e+NZlpCKd6Bd/EIdqjFJRFHbrq5TzPPLwREk5Iv/YoIjQrs6ljdAUCo+Lb2xFlGNOjGSE0dqsVD19cZL137w== "@types/inquirer@^8.1.3": - version "8.2.1" - resolved "https://registry.npmjs.org/@types/inquirer/-/inquirer-8.2.1.tgz#28a139be3105a1175e205537e8ac10830e38dbf4" - integrity sha512-wKW3SKIUMmltbykg4I5JzCVzUhkuD9trD6efAmYgN2MrSntY0SMRQzEnD3mkyJ/rv9NLbTC7g3hKKE86YwEDLw== + version "8.2.3" + resolved "https://registry.npmjs.org/@types/inquirer/-/inquirer-8.2.3.tgz#985515d04879a0d0c1f5f49ec375767410ba9dab" + integrity sha512-ZlBqD+8WIVNy3KIVkl+Qne6bGLW2erwN0GJXY9Ri/9EMbyupee3xw3H0Mmv5kJoLyNpfd/oHlwKxO0DUDH7yWA== dependencies: "@types/through" "*" - rxjs "^7.2.0" "@types/is-ci@^3.0.0": version "3.0.0" @@ -6612,14 +7107,14 @@ "@types/node" "*" "@types/lodash@^4.14.151", "@types/lodash@^4.14.173", "@types/lodash@^4.14.175": - version "4.14.182" - resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2" - integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q== + version "4.14.184" + resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.184.tgz#23f96cd2a21a28e106dc24d825d4aa966de7a9fe" + integrity sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q== "@types/long@^4.0.0", "@types/long@^4.0.1": - version "4.0.1" - resolved "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" - integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== + version "4.0.2" + resolved "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== "@types/lru-cache@^5.1.0": version "5.1.1" @@ -6631,15 +7126,15 @@ resolved "https://registry.npmjs.org/@types/lunr/-/lunr-2.3.4.tgz#728f445855818fb17776d10ef4678f278072eb03" integrity sha512-j4x4XJwZvorEUbA519VdQ5b9AOU9TSvfi8tvxMAfP8XzNLtFex7A8vFQwqOx3WACbV0KMXbACV3cZl4/gynQ7g== -"@types/luxon@*", "@types/luxon@^2.0.4", "@types/luxon@^2.0.5", "@types/luxon@^2.0.9": - version "2.3.2" - resolved "https://registry.npmjs.org/@types/luxon/-/luxon-2.3.2.tgz#8a3f2cdd4858ce698b56cd8597d9243b8e9d3c65" - integrity sha512-WOehptuhKIXukSUUkRgGbj2c997Uv/iUgYgII8U7XLJqq9W2oF0kQ6frEznRQbdurioz+L/cdaIm4GutTQfgmA== +"@types/luxon@*", "@types/luxon@^3.0.0": + version "3.0.0" + resolved "https://registry.npmjs.org/@types/luxon/-/luxon-3.0.0.tgz#47fb7891e41875fce7018a8bd3d09b204c5621f5" + integrity sha512-Lx+EZoJxUKw4dp8uei9XiUVNlgkYmax5+ovqt6Xf3LzJOnWhlfJw/jLBmqfGVwOP/pDr4HT8bI1WtxK0IChMLw== "@types/marked@^4.0.0": - version "4.0.3" - resolved "https://registry.npmjs.org/@types/marked/-/marked-4.0.3.tgz#2098f4a77adaba9ce881c9e0b6baf29116e5acc4" - integrity sha512-HnMWQkLJEf/PnxZIfbm0yGJRRZYYMhb++O9M36UCTA9z53uPvVoSlAwJr3XOpDEryb7Hwl1qAx/MV6YIW1RXxg== + version "4.0.6" + resolved "https://registry.npmjs.org/@types/marked/-/marked-4.0.6.tgz#9ca544c1057f3c8b3f649b5e8e56d9241e3ca22d" + integrity sha512-ITAVUzsnVbhy5afxhs4PPPbrv2hKVEDH5BhhaQNQlVG0UNu+9A18XSdYr53nBdHZ0ADEQLl+ciOjXbs7eHdiQQ== "@types/mdast@^3.0.0", "@types/mdast@^3.0.3": version "3.0.10" @@ -6715,7 +7210,7 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node@*", "@types/node@>= 8", "@types/node@>=12.12.47", "@types/node@>=13.7.0": +"@types/node@*", "@types/node@>=12.12.47", "@types/node@>=13.7.0": version "17.0.25" resolved "https://registry.npmjs.org/@types/node/-/node-17.0.25.tgz#527051f3c2f77aa52e5dc74e45a3da5fb2301448" integrity sha512-wANk6fBrUwdpY4isjWrKTufkrXdu1D2YHCot2fD/DfWxF5sMrVSA+KN7ydckvaTCh0HiqX9IVl0L5/ZoXg5M7w== @@ -6725,6 +7220,11 @@ resolved "https://registry.npmjs.org/@types/node/-/node-12.20.24.tgz#c37ac69cb2948afb4cef95f424fa0037971a9a5c" integrity sha512-yxDeaQIAJlMav7fH5AQqPH1u8YIuhYJXYBzxaQ4PifsU0GDO38MSdmEDeRlIxrKbC6NbEaaEHDanWb+y30U8SQ== +"@types/node@>= 8": + version "18.7.4" + resolved "https://registry.npmjs.org/@types/node/-/node-18.7.4.tgz#95baa50846ae112a7376869d49fec23b2506c69d" + integrity sha512-RzRcw8c0B8LzryWOR4Wj7YOTFXvdYKwvrb6xQQyuDfnlTxwYXGCV5RZ/TEbq5L5kn+w3rliHAUyRcG1RtbmTFg== + "@types/node@^10.1.0", "@types/node@^10.12.0": version "10.17.60" resolved "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" @@ -6746,9 +7246,9 @@ integrity sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A== "@types/node@^16.0.0", "@types/node@^16.11.26", "@types/node@^16.9.2": - version "16.11.45" - resolved "https://registry.npmjs.org/@types/node/-/node-16.11.45.tgz#155b13a33c665ef2b136f7f245fa525da419e810" - integrity sha512-3rKg/L5x0rofKuuUt5zlXzOnKyIHXmIu5R8A0TuNDMF2062/AOIDBciFIjToLEJ/9F9DzkHNot+BpNsMI1OLdQ== + version "16.11.52" + resolved "https://registry.npmjs.org/@types/node/-/node-16.11.52.tgz#d797437435455f237800c171d05639f0335c37b9" + integrity sha512-GnstYouCa9kbYokBCWEVrszJ1P2rGAQpKrqACHKuixkaT8XGu8nsqHvEUIGqDs5vwtsJ7LrYqnPDKRD1V+M39A== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -6842,9 +7342,9 @@ "@types/passport" "*" "@types/passport@*", "@types/passport@^1.0.3": - version "1.0.9" - resolved "https://registry.npmjs.org/@types/passport/-/passport-1.0.9.tgz#b32fa8f7485dace77a9b58e82d0c92908f6e8387" - integrity sha512-9+ilzUhmZQR4JP49GdC2O4UdDE3POPLwpmaTC/iLkW7l0TZCXOo1zsTnnlXPq6rP1UsUZPfbAV4IUdiwiXyC7g== + version "1.0.10" + resolved "https://registry.npmjs.org/@types/passport/-/passport-1.0.10.tgz#c518f2bae8b1538b7be71ee7f9220fbd3f569f05" + integrity sha512-IZamnXuN7mY+2/v8bAW6nuTcKiay7gXBBcMBZ8n7YHB4u5DwsWoJaNrHdAQ8PZEODRjCv3oHOg76CYJ40j9RqA== dependencies: "@types/express" "*" @@ -6912,9 +7412,9 @@ "@types/react" "*" "@types/react-syntax-highlighter@^15.0.0": - version "15.5.3" - resolved "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.3.tgz#6f23839167ac254d922a0db918cb0d37bd2abff0" - integrity sha512-N5bgZxolo+wFuYnx4nOvIQO2P0E+KYHt3dDwb8ydUvZ96QN8Lpq60ReT+0W0JmXKZjp4udkYkIDYt9GIygBY1Q== + version "15.5.4" + resolved "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.4.tgz#c76dd9cab769484bb7360849074eb340421183ca" + integrity sha512-GYXA4nRBG4jTGFfYMLO2/yuqyOyaQ415oeJWw6akE5gipOEsGhvXFvWhsctGVMHzAfRI7e/J0B9cpqrfMOwZhA== dependencies: "@types/react" "*" @@ -7042,9 +7542,9 @@ integrity sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A== "@types/semver@^7.3.8": - version "7.3.10" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.3.10.tgz#5f19ee40cbeff87d916eedc8c2bfe2305d957f73" - integrity sha512-zsv3fsC7S84NN6nPK06u79oWgrPVd0NvOyqgghV1haPaFcVxIrP4DLomRwGAXk0ui4HZA7mOcSFL98sMVW9viw== + version "7.3.12" + resolved "https://registry.npmjs.org/@types/semver/-/semver-7.3.12.tgz#920447fdd78d76b19de0438b7f60df3c4a80bf1c" + integrity sha512-WwA1MW0++RfXmCr12xeYOOC5baSC9mSb0ZqCquFzKhcoF4TvHu5MKOuXsncgZcpVFhB1pXd5hZmM0ryAoCp12A== "@types/serve-handler@^6.1.0": version "6.1.1" @@ -7149,7 +7649,7 @@ "@types/cookiejar" "*" "@types/node" "*" -"@types/supertest@^2.0.8": +"@types/supertest@^2.0.12", "@types/supertest@^2.0.8": version "2.0.12" resolved "https://registry.npmjs.org/@types/supertest/-/supertest-2.0.12.tgz#ddb4a0568597c9aadff8dbec5b2e8fddbe8692fc" integrity sha512-X3HPWTwXRerBZS7Mo1k6vMVR1Z6zmJcDVn5O/31whe0tnjE4te6ZJSJGq1RiqHPjzPdMTfjCFogDJmwng9xHaQ== @@ -7157,9 +7657,9 @@ "@types/superagent" "*" "@types/svgo@^2.6.2": - version "2.6.3" - resolved "https://registry.npmjs.org/@types/svgo/-/svgo-2.6.3.tgz#0786d8329b67cd48d84e57cb92b79832b85e6c8e" - integrity sha512-5sP0Xgo0dXppY0tbYF6TevB/1+tzFLuu71XXxC/zGvQAn9PW7y+DwtDO81g0ZUPye00K6tPwtsLDOpARa0mFcA== + version "2.6.4" + resolved "https://registry.npmjs.org/@types/svgo/-/svgo-2.6.4.tgz#b7298fc1dd687539fd63fc818b00146d96e68836" + integrity sha512-l4cmyPEckf8moNYHdJ+4wkHvFxjyW6ulm9l4YGaOxeyBWPhBOT0gvni1InpFPdzx1dKf/2s62qGITwxNWnPQng== dependencies: "@types/node" "*" @@ -7179,12 +7679,12 @@ "@types/node" "*" "@types/tar@^6.1.1": - version "6.1.1" - resolved "https://registry.npmjs.org/@types/tar/-/tar-6.1.1.tgz#ab341ec1f149d7eb2a4f4ded56ff85f0d4fe7cb5" - integrity sha512-8mto3YZfVpqB1CHMaYz1TUYIQfZFbh/QbEq5Hsn6D0ilCfqRVCdalmc89B7vi3jhl9UYIk+dWDABShNfOkv5HA== + version "6.1.2" + resolved "https://registry.npmjs.org/@types/tar/-/tar-6.1.2.tgz#e60108a7d1b08cc91bf2faf1286cc08fdad48bbe" + integrity sha512-bnX3RRm70/n1WMwmevdOAeDU4YP7f5JSubgnuU+yrO+xQQjwDboJj3u2NTJI5ngCQhXihqVVAH5h5J8YpdpEvg== dependencies: - "@types/minipass" "*" "@types/node" "*" + minipass "^3.3.5" "@types/tern@*": version "0.23.4" @@ -7241,13 +7741,6 @@ resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== -"@types/unzipper@^0.10.3": - version "0.10.5" - resolved "https://registry.npmjs.org/@types/unzipper/-/unzipper-0.10.5.tgz#36a963cf025162b4ac31642590cb4192971d633b" - integrity sha512-NrLJb29AdnBARpg9S/4ktfPEisbJ0AvaaAr3j7Q1tg8AgcEUsq2HqbNzvgLRoWyRtjzeLEv7vuL39u1mrNIyNA== - dependencies: - "@types/node" "*" - "@types/uuid@^8.0.0": version "8.3.4" resolved "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" @@ -7262,9 +7755,9 @@ "@types/node" "*" "@types/webpack-env@^1.15.2", "@types/webpack-env@^1.15.3": - version "1.17.0" - resolved "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.17.0.tgz#f99ce359f1bfd87da90cc4a57cab0a18f34a48d0" - integrity sha512-eHSaNYEyxRA5IAG0Ym/yCyf86niZUIF/TpWKofQI/CVfh5HsMEUyfE2kwFxha4ow0s5g0LfISQxpDKjbRDrizw== + version "1.18.0" + resolved "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.0.tgz#ed6ecaa8e5ed5dfe8b2b3d00181702c9925f13fb" + integrity sha512-56/MAlX5WMsPVbOg7tAxnYvNYMMWr/QJiIp6BxVSW3JJXUVzzOn64qW8TzQyMSqSUFM2+PVI4aUHcHOzIz/1tg== "@types/webpack@^5.28.0": version "5.28.0" @@ -7320,6 +7813,13 @@ resolved "https://registry.npmjs.org/@types/yarnpkg__lockfile/-/yarnpkg__lockfile-1.1.5.tgz#9639020e1fb65120a2f4387db8f1e8b63efdf229" integrity sha512-8NYnGOctzsI4W0ApsP/BIHD/LnxpJ6XaGf2AZmz4EyDYJMxtprN4279dLNI1CPZcwC9H18qYcaFv4bXi0wmokg== +"@types/yauzl@^2.10.0": + version "2.10.0" + resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz#b3248295276cf8c6f153ebe6a9aba0c988cb2599" + integrity sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw== + dependencies: + "@types/node" "*" + "@types/yauzl@^2.9.1": version "2.9.2" resolved "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.9.2.tgz#c48e5d56aff1444409e39fa164b0b4d4552a7b7a" @@ -7338,13 +7838,13 @@ integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw== "@typescript-eslint/eslint-plugin@^5.9.0": - version "5.30.6" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.30.6.tgz#9c6017b6c1d04894141b4a87816388967f64c359" - integrity sha512-J4zYMIhgrx4MgnZrSDD7sEnQp7FmhKNOaqaOpaoQ/SfdMfRB/0yvK74hTnvH+VQxndZynqs5/Hn4t+2/j9bADg== + version "5.33.1" + resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.33.1.tgz#c0a480d05211660221eda963cc844732fe9b1714" + integrity sha512-S1iZIxrTvKkU3+m63YUOxYPKaP+yWDQrdhxTglVDVEVBf+aCSw85+BmJnyUaQQsk5TXFG/LpBu9fa+LrAQ91fQ== dependencies: - "@typescript-eslint/scope-manager" "5.30.6" - "@typescript-eslint/type-utils" "5.30.6" - "@typescript-eslint/utils" "5.30.6" + "@typescript-eslint/scope-manager" "5.33.1" + "@typescript-eslint/type-utils" "5.33.1" + "@typescript-eslint/utils" "5.33.1" debug "^4.3.4" functional-red-black-tree "^1.0.1" ignore "^5.2.0" @@ -7365,13 +7865,13 @@ eslint-utils "^3.0.0" "@typescript-eslint/parser@^5.9.0": - version "5.30.6" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.30.6.tgz#add440db038fa9d777e4ebdaf66da9e7fb7abe92" - integrity sha512-gfF9lZjT0p2ZSdxO70Xbw8w9sPPJGfAdjK7WikEjB3fcUI/yr9maUVEdqigBjKincUYNKOmf7QBMiTf719kbrA== + version "5.33.1" + resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.33.1.tgz#e4b253105b4d2a4362cfaa4e184e2d226c440ff3" + integrity sha512-IgLLtW7FOzoDlmaMoXdxG8HOCByTBXrB1V2ZQYSEV1ggMmJfAkMWTwUjjzagS6OkfpySyhKFkBw7A9jYmcHpZA== dependencies: - "@typescript-eslint/scope-manager" "5.30.6" - "@typescript-eslint/types" "5.30.6" - "@typescript-eslint/typescript-estree" "5.30.6" + "@typescript-eslint/scope-manager" "5.33.1" + "@typescript-eslint/types" "5.33.1" + "@typescript-eslint/typescript-estree" "5.33.1" debug "^4.3.4" "@typescript-eslint/scope-manager@5.20.0": @@ -7382,13 +7882,13 @@ "@typescript-eslint/types" "5.20.0" "@typescript-eslint/visitor-keys" "5.20.0" -"@typescript-eslint/scope-manager@5.30.6": - version "5.30.6" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.30.6.tgz#ce1b49ff5ce47f55518d63dbe8fc9181ddbd1a33" - integrity sha512-Hkq5PhLgtVoW1obkqYH0i4iELctEKixkhWLPTYs55doGUKCASvkjOXOd/pisVeLdO24ZX9D6yymJ/twqpJiG3g== +"@typescript-eslint/scope-manager@5.33.1": + version "5.33.1" + resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.33.1.tgz#8d31553e1b874210018ca069b3d192c6d23bc493" + integrity sha512-8ibcZSqy4c5m69QpzJn8XQq9NnqAToC8OdH/W6IXPXv83vRyEDPYLdjAlUx8h/rbusq6MkW4YdQzURGOqsn3CA== dependencies: - "@typescript-eslint/types" "5.30.6" - "@typescript-eslint/visitor-keys" "5.30.6" + "@typescript-eslint/types" "5.33.1" + "@typescript-eslint/visitor-keys" "5.33.1" "@typescript-eslint/scope-manager@5.9.0": version "5.9.0" @@ -7398,12 +7898,12 @@ "@typescript-eslint/types" "5.9.0" "@typescript-eslint/visitor-keys" "5.9.0" -"@typescript-eslint/type-utils@5.30.6": - version "5.30.6" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.30.6.tgz#a64aa9acbe609ab77f09f53434a6af2b9685f3af" - integrity sha512-GFVVzs2j0QPpM+NTDMXtNmJKlF842lkZKDSanIxf+ArJsGeZUIaeT4jGg+gAgHt7AcQSFwW7htzF/rbAh2jaVA== +"@typescript-eslint/type-utils@5.33.1": + version "5.33.1" + resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.33.1.tgz#1a14e94650a0ae39f6e3b77478baff002cec4367" + integrity sha512-X3pGsJsD8OiqhNa5fim41YtlnyiWMF/eKsEZGsHID2HcDqeSC5yr/uLOeph8rNF2/utwuI0IQoAK3fpoxcLl2g== dependencies: - "@typescript-eslint/utils" "5.30.6" + "@typescript-eslint/utils" "5.33.1" debug "^4.3.4" tsutils "^3.21.0" @@ -7412,10 +7912,10 @@ resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.20.0.tgz#fa39c3c2aa786568302318f1cb51fcf64258c20c" integrity sha512-+d8wprF9GyvPwtoB4CxBAR/s0rpP25XKgnOvMf/gMXYDvlUC3rPFHupdTQ/ow9vn7UDe5rX02ovGYQbv/IUCbg== -"@typescript-eslint/types@5.30.6": - version "5.30.6" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.30.6.tgz#86369d0a7af8c67024115ac1da3e8fb2d38907e1" - integrity sha512-HdnP8HioL1F7CwVmT4RaaMX57RrfqsOMclZc08wGMiDYJBsLGBM7JwXM4cZJmbWLzIR/pXg1kkrBBVpxTOwfUg== +"@typescript-eslint/types@5.33.1": + version "5.33.1" + resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.33.1.tgz#3faef41793d527a519e19ab2747c12d6f3741ff7" + integrity sha512-7K6MoQPQh6WVEkMrMW5QOA5FO+BOwzHSNd0j3+BlBwd6vtzfZceJ8xJ7Um2XDi/O3umS8/qDX6jdy2i7CijkwQ== "@typescript-eslint/types@5.9.0": version "5.9.0" @@ -7435,13 +7935,13 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@5.30.6": - version "5.30.6" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.30.6.tgz#a84a0d6a486f9b54042da1de3d671a2c9f14484e" - integrity sha512-Z7TgPoeYUm06smfEfYF0RBkpF8csMyVnqQbLYiGgmUSTaSXTP57bt8f0UFXstbGxKIreTwQCujtaH0LY9w9B+A== +"@typescript-eslint/typescript-estree@5.33.1": + version "5.33.1" + resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.33.1.tgz#a573bd360790afdcba80844e962d8b2031984f34" + integrity sha512-JOAzJ4pJ+tHzA2pgsWQi4804XisPHOtbvwUyqsuuq8+y5B5GMZs7lI1xDWs6V2d7gE/Ez5bTGojSK12+IIPtXA== dependencies: - "@typescript-eslint/types" "5.30.6" - "@typescript-eslint/visitor-keys" "5.30.6" + "@typescript-eslint/types" "5.33.1" + "@typescript-eslint/visitor-keys" "5.33.1" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" @@ -7461,15 +7961,15 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@5.30.6": - version "5.30.6" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.30.6.tgz#1de2da14f678e7d187daa6f2e4cdb558ed0609dc" - integrity sha512-xFBLc/esUbLOJLk9jKv0E9gD/OH966M40aY9jJ8GiqpSkP2xOV908cokJqqhVd85WoIvHVHYXxSFE4cCSDzVvA== +"@typescript-eslint/utils@5.33.1": + version "5.33.1" + resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.33.1.tgz#171725f924fe1fe82bb776522bb85bc034e88575" + integrity sha512-uphZjkMaZ4fE8CR4dU7BquOV6u0doeQAr8n6cQenl/poMaIyJtBu8eys5uk6u5HiDH01Mj5lzbJ5SfeDz7oqMQ== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.30.6" - "@typescript-eslint/types" "5.30.6" - "@typescript-eslint/typescript-estree" "5.30.6" + "@typescript-eslint/scope-manager" "5.33.1" + "@typescript-eslint/types" "5.33.1" + "@typescript-eslint/typescript-estree" "5.33.1" eslint-scope "^5.1.1" eslint-utils "^3.0.0" @@ -7493,12 +7993,12 @@ "@typescript-eslint/types" "5.20.0" eslint-visitor-keys "^3.0.0" -"@typescript-eslint/visitor-keys@5.30.6": - version "5.30.6" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.30.6.tgz#94dd10bb481c8083378d24de1742a14b38a2678c" - integrity sha512-41OiCjdL2mCaSDi2SvYbzFLlqqlm5v1ZW9Ym55wXKL/Rx6OOB1IbuFGo71Fj6Xy90gJDFTlgOS+vbmtGHPTQQA== +"@typescript-eslint/visitor-keys@5.33.1": + version "5.33.1" + resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.33.1.tgz#0155c7571c8cd08956580b880aea327d5c34a18b" + integrity sha512-nwIxOK8Z2MPWltLKMLOEZwmfBZReqUdbEoHQXeCpa+sRVARe5twpJGHCB4dk9903Yaf0nMAlGbQfaAH92F60eg== dependencies: - "@typescript-eslint/types" "5.30.6" + "@typescript-eslint/types" "5.33.1" eslint-visitor-keys "^3.3.0" "@typescript-eslint/visitor-keys@5.9.0": @@ -7509,10 +8009,10 @@ "@typescript-eslint/types" "5.9.0" eslint-visitor-keys "^3.0.0" -"@uiw/codemirror-extensions-basic-setup@4.11.4": - version "4.11.4" - resolved "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.11.4.tgz#c749a66980e18ca6651488712ea3239c82a31cdd" - integrity sha512-pc9pQtCQFmAH5nV9UmX37VB0+yzSFQ2kbSvLHBFST9siYnacaR6HxmkBBBbYYXwVK/n9pGZ6A8ZefAUNTFfo/A== +"@uiw/codemirror-extensions-basic-setup@4.11.5": + version "4.11.5" + resolved "https://registry.npmjs.org/@uiw/codemirror-extensions-basic-setup/-/codemirror-extensions-basic-setup-4.11.5.tgz#e66462bda16bb635948a6faa8ee354f5db22f0b5" + integrity sha512-aHtdF1JEzHmBVuWXemr8OH7SQP/LbXXZdiOo/4tcxjFpyTuVGzPteBdfQU0xPOk0m+5Oc1LPqM+HaNPXNzX6aA== dependencies: "@codemirror/autocomplete" "^6.0.0" "@codemirror/commands" "^6.0.0" @@ -7523,13 +8023,13 @@ "@codemirror/view" "^6.0.0" "@uiw/react-codemirror@^4.9.3": - version "4.11.4" - resolved "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.11.4.tgz#76adc757baa0b8b1a9bd30d7081f5622b896d607" - integrity sha512-p7DNBI6kj+DUzTe7MjBJwZ3qo0nSOav7T0MEGRpRNZA9ZO3RnzhPMie6swDA8e3dz1s59l9UdFB1fgyam1vFhQ== + version "4.11.5" + resolved "https://registry.npmjs.org/@uiw/react-codemirror/-/react-codemirror-4.11.5.tgz#9efead5e0f9496bda6eeb1118b67687b3b82861a" + integrity sha512-Bf8l3nVV4ekHbv4U0VrzUibl8+ucAY3UV0gk0xckbFnV1AlUxHcrYFiXSgy/rkyWBD7enHQENtM888B/3qBiwg== dependencies: "@babel/runtime" "^7.18.6" "@codemirror/theme-one-dark" "^6.0.0" - "@uiw/codemirror-extensions-basic-setup" "4.11.4" + "@uiw/codemirror-extensions-basic-setup" "4.11.5" codemirror "^6.0.0" "@webassemblyjs/ast@1.11.1": @@ -7653,6 +8153,21 @@ "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" +"@whatwg-node/fetch@^0.2.3", "@whatwg-node/fetch@^0.2.4": + version "0.2.6" + resolved "https://registry.npmjs.org/@whatwg-node/fetch/-/fetch-0.2.6.tgz#eb8e68624c55aecfa4c6d7ea36b3ce3ad5d5f79e" + integrity sha512-NhHiqeGcKjgqUZvJTZSou9qsFEPBBG1LPm2Npz0cmcPvukhhQfjX+p3quRx6b9AyjNPp1f73VB1z4ApHy9FcNg== + dependencies: + "@peculiar/webcrypto" "^1.4.0" + abort-controller "^3.0.0" + busboy "^1.6.0" + event-target-polyfill "^0.0.3" + form-data-encoder "^1.7.1" + formdata-node "^4.3.1" + node-fetch "^2.6.7" + undici "^5.8.0" + web-streams-polyfill "^3.2.0" + "@xmldom/xmldom@^0.7.0", "@xmldom/xmldom@^0.7.5": version "0.7.5" resolved "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz#09fa51e356d07d0be200642b0e4f91d8e6dd408d" @@ -7679,9 +8194,9 @@ integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== "@yarnpkg/parsers@^3.0.0-rc.4": - version "3.0.0-rc.12" - resolved "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.12.tgz#76890a00c4c14a5c38f6eef5e9ce9b9c2fb3c6da" - integrity sha512-LEijAfCE8dMhW+tRBz9EM3Ui53SX+E6Tsvzaf7opESDARK+2HAyX+M/w73oNTXCOgMRrfMVWP5wJTj9cG96uoQ== + version "3.0.0-rc.14" + resolved "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.14.tgz#3ce7fb8f9b7ecdda0531d382909c29140b11d723" + integrity sha512-vLwjxSdmRNF/pPsubkmpkAgRHBbBylRDn13gv2fyTkHjeT2257NBNefjR7Dx5gSy8PM93VZitnmtWCnXEsSvkA== dependencies: js-yaml "^3.10.0" tslib "^1.13.0" @@ -7767,16 +8282,16 @@ acorn@^7.1.1: resolved "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.0: - version "8.7.0" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf" - integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ== - -acorn@^8.4.1, acorn@^8.7.1: +acorn@^8.2.4, acorn@^8.4.1, acorn@^8.5.0, acorn@^8.7.0, acorn@^8.7.1: version "8.7.1" resolved "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== +acorn@^8.8.0: + version "8.8.0" + resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + add-stream@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" @@ -7875,9 +8390,9 @@ alphanum-sort@^1.0.2: integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= already@^3.2.0: - version "3.3.0" - resolved "https://registry.npmjs.org/already/-/already-3.3.0.tgz#a5e5becd167cf537b45f8f1c23d331488ed77003" - integrity sha512-ADGyKddqEp8t/Wu4ITc0y9GGsgZDgyMeMk38AM5qrPK7VEjNAYD87QGTGGgNhSQahmjw76V3mi+3fJRwPJXcTw== + version "3.4.0" + resolved "https://registry.npmjs.org/already/-/already-3.4.0.tgz#d32aab4be75ae2352a16f26d688393fc79675c18" + integrity sha512-l2neHYJryLga4BiKsVdO3c3E5dCl1OgkKS4pr3nDyxQRABywIyI3MuNaUypj2tLQKy7PFJ5CUrQ7Waa+eVn4Fg== anafanafo@2.0.0: version "2.0.0" @@ -7987,10 +8502,10 @@ apollo-reporting-protobuf@^3.3.2: dependencies: "@apollo/protobufjs" "1.2.4" -apollo-server-core@^3.10.0: - version "3.10.0" - resolved "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-3.10.0.tgz#6680b4eb4699829ed50d8a592721ee5e5e11e041" - integrity sha512-ln5drIk3oW/ycYhcYL9TvM7vRf7OZwJrgHWlnjnMakozBQIBSumdMi4pN001DhU9mVBWTfnmBv3CdcxJdGXIvA== +apollo-server-core@^3.10.1: + version "3.10.1" + resolved "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-3.10.1.tgz#01f9ffc57c7d15c27bd7f89d65f45522aa3f3c3d" + integrity sha512-UFFziv6h15QbKRZOA6wLyr1Sle9kns3JuQ5DEB7OYe5AIoOJNjZkWXX/tmLFUrSmlnDDryi6Sf5pDzpYmUC/UA== dependencies: "@apollo/utils.keyvaluecache" "^1.0.1" "@apollo/utils.logger" "^1.0.0" @@ -8027,18 +8542,18 @@ apollo-server-errors@^3.3.1: resolved "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-3.3.1.tgz#ba5c00cdaa33d4cbd09779f8cb6f47475d1cd655" integrity sha512-xnZJ5QWs6FixHICXHxUfm+ZWqqxrNuPlQ+kj5m6RtEgIpekOPssH/SD9gf2B4HuWV0QozorrygwZnux8POvyPA== -apollo-server-express@^3.0.0, apollo-server-express@^3.10.0: - version "3.10.0" - resolved "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-3.10.0.tgz#fd276cf36031f7a02936cce6d170a35e1c084701" - integrity sha512-ww3tZq9I/x3Oxtux8xlHAZcSB0NNQ17lRlY6yCLk1F+jCzdcjuj0x8XNg0GdTrMowt5v43o786bU9VYKD5OVnA== +apollo-server-express@^3.0.0, apollo-server-express@^3.10.1: + version "3.10.1" + resolved "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-3.10.1.tgz#b0262d3c4919b554cff5872639bb13b694b5a217" + integrity sha512-r0esst3YGNdlphYiOrflfBqJ15VAZAhYhWSFo2kPF4knsIGK5HUkeqwjMr+fFDBn4DEfYzC+I1+LnsF/hFN8VQ== dependencies: "@types/accepts" "^1.3.5" "@types/body-parser" "1.19.2" "@types/cors" "2.8.12" "@types/express" "4.17.13" - "@types/express-serve-static-core" "4.17.29" + "@types/express-serve-static-core" "4.17.30" accepts "^1.3.5" - apollo-server-core "^3.10.0" + apollo-server-core "^3.10.1" apollo-server-types "^3.6.2" body-parser "^1.19.0" cors "^2.8.5" @@ -8062,13 +8577,13 @@ apollo-server-types@^3.6.2: apollo-server-env "^4.2.1" apollo-server@^3.0.0: - version "3.10.0" - resolved "https://registry.npmjs.org/apollo-server/-/apollo-server-3.10.0.tgz#ed4b0b4cc5e1f44260923a4317caa663f1a3824e" - integrity sha512-6PAz1XZFM9+K2+QUCXXxQIlZy5mhSOhg0rTx3ZNbIdy1fFNP+6ZjvQAJxBIyEtaKlC2yEPAOg4yi3u8WfuA3bA== + version "3.10.1" + resolved "https://registry.npmjs.org/apollo-server/-/apollo-server-3.10.1.tgz#ed0c39d706a6a232885680c001df3b90c5cb0902" + integrity sha512-2e7EN7Pw+vV7vP236zozuFVMLjeY6Q8lF1VzT+j32pZ2oYuTrDv+9lFjMjTBPK2yV5kzuOwJU4dWkWx5OKDEiQ== dependencies: "@types/express" "4.17.13" - apollo-server-core "^3.10.0" - apollo-server-express "^3.10.0" + apollo-server-core "^3.10.1" + apollo-server-express "^3.10.1" express "^4.17.1" aproba@^1.0.3: @@ -8328,6 +8843,15 @@ asn1@^0.2.4, asn1@~0.2.3: dependencies: safer-buffer "~2.1.0" +asn1js@^3.0.1, asn1js@^3.0.5: + version "3.0.5" + resolved "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz#5ea36820443dbefb51cc7f88a2ebb5b462114f38" + integrity sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ== + dependencies: + pvtsutils "^1.3.2" + pvutils "^1.1.3" + tslib "^2.4.0" + assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" @@ -8446,9 +8970,9 @@ aws-sdk-mock@^5.2.1: traverse "^0.6.6" aws-sdk@^2.1122.0, aws-sdk@^2.814.0, aws-sdk@^2.840.0, aws-sdk@^2.948.0: - version "2.1176.0" - resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1176.0.tgz#f3524433a60857a8fcd21722251f2b1f19d72008" - integrity sha512-jinSKjACYHIkkz0UlFwQXwz8HAHZIeJg5wOnZoMTKU3/WM6Vh26hZJJ6XkwDAfBmyWp3V9qFdQoSAiO8SeXKjw== + version "2.1199.0" + resolved "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1199.0.tgz#1279a2086c34232a450f032543fd43e98e3d8232" + integrity sha512-N51EMTCMsiVAJDSKCDTMUheLBlPZ7/c/qyCMGirdoF64/JU+gvZ/u+UqkYPhK7XE80b0GqTj676rtp9OkU1kyg== dependencies: buffer "4.9.2" events "1.1.1" @@ -8471,10 +8995,10 @@ aws4@^1.11.0, aws4@^1.8.0: resolved "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -axe-core@^4.4.2: - version "4.4.2" - resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.4.2.tgz#dcf7fb6dea866166c3eab33d68208afe4d5f670c" - integrity sha512-LVAaGp/wkkgYJcjmHsoKx4juT1aQvJyPcW09MLCjVTh3V2cc6PnyempiLMNH5iMdfIX/zdbjUx2KDjMLCTdPeA== +axe-core@^4.4.3: + version "4.4.3" + resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f" + integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w== axios-cached-dns-resolve@0.5.2: version "0.5.2" @@ -8562,7 +9086,7 @@ babel-plugin-jest-hoist@^27.5.1: "@types/babel__core" "^7.0.0" "@types/babel__traverse" "^7.0.6" -babel-plugin-polyfill-corejs2@^0.3.0: +babel-plugin-polyfill-corejs2@^0.3.1: version "0.3.1" resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== @@ -8571,15 +9095,15 @@ babel-plugin-polyfill-corejs2@^0.3.0: "@babel/helper-define-polyfill-provider" "^0.3.1" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.5.0: - version "0.5.1" - resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz#d66183bf10976ea677f4149a7fcc4d8df43d4060" - integrity sha512-TihqEe4sQcb/QcPJvxe94/9RZuLQuF1+To4WqQcRvc+3J3gLCPIPgDKzGLG6zmQLfH3nn25heRuDNkS2KR4I8A== +babel-plugin-polyfill-corejs3@^0.5.2: + version "0.5.2" + resolved "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" + integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== dependencies: "@babel/helper-define-polyfill-provider" "^0.3.1" - core-js-compat "^3.20.0" + core-js-compat "^3.21.0" -babel-plugin-polyfill-regenerator@^0.3.0: +babel-plugin-polyfill-regenerator@^0.3.1: version "0.3.1" resolved "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== @@ -8683,7 +9207,7 @@ babel-runtime@^6.26.0: core-js "^2.4.0" regenerator-runtime "^0.11.0" -backo2@1.0.2: +backo2@1.0.2, backo2@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= @@ -8805,7 +9329,7 @@ bfj@^7.0.2: hoopy "^0.1.4" tryer "^1.0.1" -big-integer@^1.6.16, big-integer@^1.6.17: +big-integer@^1.6.16: version "1.6.51" resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== @@ -8847,14 +9371,6 @@ binary-search@^1.3.5: resolved "https://registry.npmjs.org/binary-search/-/binary-search-1.3.6.tgz#e32426016a0c5092f0f3598836a1c7da3560565c" integrity sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA== -binary@~0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79" - integrity sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk= - dependencies: - buffers "~0.1.1" - chainsaw "~0.1.0" - binaryextensions@^4.15.0, binaryextensions@^4.16.0: version "4.18.0" resolved "https://registry.npmjs.org/binaryextensions/-/binaryextensions-4.18.0.tgz#22aeada2d14de062c60e8ca59a504a5636a76ceb" @@ -8896,11 +9412,6 @@ bluebird@3.7.2, bluebird@^3.3.5, bluebird@^3.5.5, bluebird@^3.7.2: resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bluebird@~3.4.1: - version "3.4.7" - resolved "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3" - integrity sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM= - bmp-js@^0.1.0: version "0.1.0" resolved "https://registry.npmjs.org/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" @@ -9103,7 +9614,7 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1, browserslist@^4.19.1: +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.6, browserslist@^4.17.5, browserslist@^4.18.1: version "4.19.1" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== @@ -9114,6 +9625,16 @@ browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4 node-releases "^2.0.1" picocolors "^1.0.0" +browserslist@^4.20.2, browserslist@^4.21.2: + version "4.21.2" + resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz#59a400757465535954946a400b841ed37e2b4ecf" + integrity sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA== + dependencies: + caniuse-lite "^1.0.30001366" + electron-to-chromium "^1.4.188" + node-releases "^2.0.6" + update-browserslist-db "^1.0.4" + bser@2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -9142,14 +9663,9 @@ buffer-equal@0.0.1: integrity sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs= buffer-from@^1.0.0: - version "1.1.1" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" - integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== - -buffer-indexof-polyfill@~1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz#d2732135c5999c64b277fcf9b1abe3498254729c" - integrity sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A== + version "1.1.2" + resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== buffer-writer@2.0.0: version "2.0.0" @@ -9186,11 +9702,6 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" -buffers@~0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb" - integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s= - builtin-modules@^3.0.0: version "3.2.0" resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" @@ -9411,6 +9922,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001286: resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001315.tgz#f1b1efd1171ee1170d52709a7252632dacbd7c77" integrity sha512-5v7LFQU4Sb/qvkz7JcZkvtSH1Ko+1x2kgo3ocdBeMGZSOFpuE1kkm0kpTwLtWeFrw5qw08ulLxJjVIXIS8MkiQ== +caniuse-lite@^1.0.30001366: + version "1.0.30001367" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz#2b97fe472e8fa29c78c5970615d7cd2ee414108a" + integrity sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw== + canvas@^2.6.1: version "2.9.3" resolved "https://registry.npmjs.org/canvas/-/canvas-2.9.3.tgz#8723c4f970442d4cdcedba5221579f9660a58bdb" @@ -9439,13 +9955,6 @@ ccount@^2.0.0: resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.0.tgz#3d6fb55803832766a24c6f339abc507297eb5d25" integrity sha512-VOR0NWFYX65n9gELQdcpqsie5L5ihBXuZGAgaPEp/U7IOSjnPMEH6geE+2f6lcekaNEfWzAHS45mPvSo5bqsUA== -chainsaw@~0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98" - integrity sha1-XqtQsor+WAdNDVgpE4iCi15fvJg= - dependencies: - traverse ">=0.3.0 <0.4" - chalk@2.4.2, chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -9935,16 +10444,16 @@ colord@^2.9.1: resolved "https://registry.npmjs.org/colord/-/colord-2.9.1.tgz#c961ea0efeb57c9f0f4834458f26cb9cc4a3f90e" integrity sha512-4LBMSt09vR0uLnPVkOUBnmxgoaeN4ewRbx801wY/bXcltXfpR/G46OdWn96XpYmCWuYvO46aBZP4NgX8HpNAcw== -colorette@2.0.16, colorette@^2.0.10: - version "2.0.16" - resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" - integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== - -colorette@^2.0.16, colorette@^2.0.17: +colorette@2.0.19, colorette@^2.0.16, colorette@^2.0.17: version "2.0.19" resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== +colorette@^2.0.10: + version "2.0.16" + resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + colors@1.0.3: version "1.0.3" resolved "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" @@ -9998,16 +10507,21 @@ command-exists@^1.2.9: resolved "https://registry.npmjs.org/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== -commander@*, commander@8.3.0, commander@^8.3.0: - version "8.3.0" - resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +commander@*, commander@^9.1.0, commander@^9.3.0: + version "9.4.0" + resolved "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c" + integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw== commander@7.1.0: version "7.1.0" resolved "https://registry.npmjs.org/commander/-/commander-7.1.0.tgz#f2eaecf131f10e36e07d894698226e36ae0eb5ff" integrity sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg== +commander@8.3.0, commander@^8.3.0: + version "8.3.0" + resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + commander@^2.20.0, commander@^2.20.3, commander@^2.7.1: version "2.20.3" resolved "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -10033,11 +10547,6 @@ commander@^7.2.0: resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== -commander@^9.1.0, commander@^9.3.0: - version "9.4.0" - resolved "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c" - integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw== - common-ancestor-path@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz#4f7d2d1394d91b7abdf51871c62f71eadb0182a7" @@ -10180,9 +10689,9 @@ concurrently@6.5.1: yargs "^16.2.0" concurrently@^7.0.0: - version "7.2.2" - resolved "https://registry.npmjs.org/concurrently/-/concurrently-7.2.2.tgz#4ad4a4dfd3945f668d727379de2a29502e6a531c" - integrity sha512-DcQkI0ruil5BA/g7Xy3EWySGrFJovF5RYAYxwGvv9Jf9q9B1v3jPFP2tl6axExNf1qgF30kjoNYrangZ0ey4Aw== + version "7.3.0" + resolved "https://registry.npmjs.org/concurrently/-/concurrently-7.3.0.tgz#eb45cdbc8df43da195f619aba218a980cae49184" + integrity sha512-IiDwm+8DOcFEInca494A8V402tNTQlJaYq78RF2rijOrKEk/AOHTxhN4U1cp7GYKYX5Q6Ymh1dLTBlzIMN0ikA== dependencies: chalk "^4.1.0" date-fns "^2.16.1" @@ -10395,12 +10904,12 @@ copy-to-clipboard@^3, copy-to-clipboard@^3.2.0, copy-to-clipboard@^3.3.1: dependencies: toggle-selection "^1.0.6" -core-js-compat@^3.20.0, core-js-compat@^3.20.2: - version "3.20.3" - resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.20.3.tgz#d71f85f94eb5e4bea3407412e549daa083d23bd6" - integrity sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw== +core-js-compat@^3.21.0, core-js-compat@^3.22.1: + version "3.23.5" + resolved "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.23.5.tgz#11edce2f1c4f69a96d30ce77c805ce118909cd5b" + integrity sha512-fHYozIFIxd+91IIbXJgWd/igXIc8Mf9is0fusswjnGIWVG96y2cwyUdlCkGOw6rMLHKAxg7xtCIVaHsyOUnJIg== dependencies: - browserslist "^4.19.1" + browserslist "^4.21.2" semver "7.0.0" core-js-pure@^3.20.2, core-js-pure@^3.6.5: @@ -10414,9 +10923,9 @@ core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.10: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.4.1, core-js@^3.6.5: - version "3.23.5" - resolved "https://registry.npmjs.org/core-js/-/core-js-3.23.5.tgz#1f82b0de5eece800827a2f59d597509c67650475" - integrity sha512-7Vh11tujtAZy82da4duVreQysIoO2EvVrur7y6IzZkH1IHPSekuDi8Vuw1+YKjkbfWLRD7Nc9ICQ/sIUDutcyg== + version "3.24.1" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.24.1.tgz#cf7724d41724154010a6576b7b57d94c5d66e64f" + integrity sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -10559,17 +11068,6 @@ cross-spawn@^5.1.0: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.0: - version "6.0.5" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -10710,15 +11208,6 @@ css.escape@1.5.1, css.escape@^1.5.1: resolved "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= -css@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" - integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== - dependencies: - inherits "^2.0.4" - source-map "^0.6.1" - source-map-resolve "^0.6.0" - cssesc@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -10860,9 +11349,9 @@ cypress-plugin-snapshots@^1.4.4: unidiff "1.0.2" cypress@^10.0.0: - version "10.3.0" - resolved "https://registry.npmjs.org/cypress/-/cypress-10.3.0.tgz#fae8d32f0822fcfb938e79c7c31ef344794336ae" - integrity sha512-txkQWKzvBVnWdCuKs5Xc08gjpO89W2Dom2wpZgT9zWZT5jXxqPIxqP/NC1YArtkpmp3fN5HW8aDjYBizHLUFvg== + version "10.6.0" + resolved "https://registry.npmjs.org/cypress/-/cypress-10.6.0.tgz#13f46867febf2c3715874ed5dce9c2e946b175fe" + integrity sha512-6sOpHjostp8gcLO34p6r/Ci342lBs8S5z9/eb3ZCQ22w2cIhMWGUoGKkosabPBfKcvRS9BE4UxybBtlIs8gTQA== dependencies: "@cypress/request" "^2.88.10" "@cypress/xvfb" "^1.2.4" @@ -11417,6 +11906,11 @@ dequal@^2.0.0: resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d" integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug== +dequal@^2.0.2: + version "2.0.3" + resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + des.js@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" @@ -11473,10 +11967,10 @@ detect-port-alt@^1.1.6: address "^1.0.1" debug "^2.6.0" -devtools-protocol@0.0.1011705: - version "0.0.1011705" - resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1011705.tgz#2582ed29f84848df83fba488122015540a744539" - integrity sha512-OKvTvu9n3swmgYshvsyVHYX0+aPzCoYUnyXUacfQMmFtBtBKewV/gT4I9jkAbpTqtTi2E4S9MXLlvzBDUlqg0Q== +devtools-protocol@0.0.1019158: + version "0.0.1019158" + resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1019158.tgz#4b08d06108a784a2134313149626ba55f030a86f" + integrity sha512-wvq+KscQ7/6spEV7czhnZc9RM/woz1AY+/Vpd8/h2HFMwJSdTliu7f/yr1A6vDdJfKICZsShqsYpEQbdhg8AFQ== dezalgo@1.0.3, dezalgo@^1.0.0: version "1.0.3" @@ -11579,10 +12073,11 @@ docker-modem@^3.0.0: ssh2 "^1.4.0" dockerode@^3.3.1: - version "3.3.2" - resolved "https://registry.npmjs.org/dockerode/-/dockerode-3.3.2.tgz#f3545700d2f7f86141b58843a755eeb21e38d5cd" - integrity sha512-oXN+1XVH2TeyE0Jj9Ci6Fim8ZIDxyqeJrkx9qhEOaRiA+nhLihKfd3M2L+Aqrj5C2ObPw8RVN2zPWvvk0x2dwg== + version "3.3.4" + resolved "https://registry.npmjs.org/dockerode/-/dockerode-3.3.4.tgz#875de614a1be797279caa9fe27e5637cf0e40548" + integrity sha512-3EUwuXnCU+RUlQEheDjmBE0B7q66PV9Rw5NiH1sXwINq0M9c5ERP9fxgkw36ZHOtzf4AGEEYySnkx/sACC9EgQ== dependencies: + "@balena/dockerignore" "^1.0.2" docker-modem "^3.0.0" tar-fs "~2.0.1" @@ -11665,15 +12160,10 @@ domhandler@^4.0.0, domhandler@^4.2.0: dependencies: domelementtype "^2.2.0" -dompurify@=2.3.3: - version "2.3.3" - resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.3.3.tgz#c1af3eb88be47324432964d8abc75cf4b98d634c" - integrity sha512-dqnqRkPMAjOZE0FogZ+ceJNM2dZ3V/yNOuFB7+39qpO93hHhfRpHw3heYQC7DPK9FqbQTfBKUJhiSfz4MvXYwg== - -dompurify@^2.2.7, dompurify@^2.2.9, dompurify@^2.3.6: - version "2.3.9" - resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.3.9.tgz#a4be5e7278338d6db09922dffcf6182cd099d70a" - integrity sha512-3zOnuTwup4lPV/GfGS6UzG4ub9nhSYagR/5tB3AvDEwqyy5dtyCM2dVjwGDCnrPerXifBKTYh/UWCGKK7ydhhw== +dompurify@=2.3.10, dompurify@^2.2.7, dompurify@^2.2.9, dompurify@^2.3.6: + version "2.3.10" + resolved "https://registry.npmjs.org/dompurify/-/dompurify-2.3.10.tgz#901f7390ffe16a91a5a556b94043314cd4850385" + integrity sha512-o7Fg/AgC7p/XpKjf/+RC3Ok6k4St5F7Q6q6+Nnm3p2zGWioAY6dh0CbbuwOhH2UcSzKsdniE/YnE2/92JcsA+g== domutils@^2.5.2, domutils@^2.6.0: version "2.8.0" @@ -11721,13 +12211,6 @@ dset@^3.1.2: resolved "https://registry.npmjs.org/dset/-/dset-3.1.2.tgz#89c436ca6450398396dc6538ea00abc0c54cd45a" integrity sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q== -duplexer2@~0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" - integrity sha1-ixLauHjA1p4+eJEFFmKjL8a93ME= - dependencies: - readable-stream "^2.0.2" - duplexer@^0.1.1, duplexer@~0.1.1: version "0.1.1" resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" @@ -11738,7 +12221,7 @@ duplexer@^0.1.2: resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== -duplexify@^4.0.0, duplexify@^4.1.1: +duplexify@^4.0.0: version "4.1.1" resolved "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz#7027dc374f157b122a8ae08c2d3ea4d2d953aa61" integrity sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA== @@ -11760,6 +12243,11 @@ easy-table@1.1.0: optionalDependencies: wcwidth ">=1.0.1" +ebnf@^1.9.0: + version "1.9.0" + resolved "https://registry.npmjs.org/ebnf/-/ebnf-1.9.0.tgz#9c2dd6052f3ed43a69c1f0b07b15bd03cefda764" + integrity sha512-LKK899+j758AgPq00ms+y90mo+2P86fMKUWD28sH0zLKUj7aL6iIH2wy4jejAMM9I2BawJ+2kp6C3mMXj+Ii5g== + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -11807,6 +12295,11 @@ electron-to-chromium@^1.4.17: resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.35.tgz#69aabb73d7030733e71c1e970ec16f5ceefbaea4" integrity sha512-wzTOMh6HGFWeALMI3bif0mzgRrVGyP1BdFRx7IvWukFrSC5QVQELENuy+Fm2dCrAdQH9T3nuqr07n94nPDFBWA== +electron-to-chromium@^1.4.188: + version "1.4.194" + resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.194.tgz#2f83fcec5067907044a3d502ac7c3efb1fe6430b" + integrity sha512-ola5UH0xAP1oYY0FFUsPvwtucEzCQHucXnT7PQ1zjHJMccZhCDktEugI++JUR3YuIs7Ff7afz+OVEhVAIMhLAQ== + elliptic@^6.0.0: version "6.5.4" resolved "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" @@ -11904,10 +12397,10 @@ engine.io@~3.5.0: engine.io-parser "~2.2.0" ws "~7.4.2" -enhanced-resolve@^5.9.3: - version "5.9.3" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88" - integrity sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow== +enhanced-resolve@^5.10.0: + version "5.10.0" + resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -11929,10 +12422,10 @@ entities@^2.0.0, entities@~2.1.0: resolved "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== -entities@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" - integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q== +entities@^4.3.0: + version "4.3.1" + resolved "https://registry.npmjs.org/entities/-/entities-4.3.1.tgz#c34062a94c865c322f9d67b4384e4169bcede6a4" + integrity sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg== env-paths@^2.2.0: version "2.2.0" @@ -12054,75 +12547,75 @@ es6-error@^4.1.1: resolved "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== -esbuild-android-64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.49.tgz#9e4682c36dcf6e7b71b73d2a3723a96e0fdc5054" - integrity sha512-vYsdOTD+yi+kquhBiFWl3tyxnj2qZJsl4tAqwhT90ktUdnyTizgle7TjNx6Ar1bN7wcwWqZ9QInfdk2WVagSww== +esbuild-android-64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.54.tgz#505f41832884313bbaffb27704b8bcaa2d8616be" + integrity sha512-Tz2++Aqqz0rJ7kYBfz+iqyE3QMycD4vk7LBRyWaAVFgFtQ/O8EJOnVmTOiDWYZ/uYzB4kvP+bqejYdVKzE5lAQ== -esbuild-android-arm64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.49.tgz#9861b1f7e57d1dd1f23eeef6198561c5f34b51f6" - integrity sha512-g2HGr/hjOXCgSsvQZ1nK4nW/ei8JUx04Li74qub9qWrStlysaVmadRyTVuW32FGIpLQyc5sUjjZopj49eGGM2g== +esbuild-android-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.54.tgz#8ce69d7caba49646e009968fe5754a21a9871771" + integrity sha512-F9E+/QDi9sSkLaClO8SOV6etqPd+5DgJje1F9lOWoNncDdOBL2YF59IhsWATSt0TLZbYCf3pNlTHvVV5VfHdvg== -esbuild-darwin-64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.49.tgz#fd30a5ebe28704a3a117126c60f98096c067c8d1" - integrity sha512-3rvqnBCtX9ywso5fCHixt2GBCUsogNp9DjGmvbBohh31Ces34BVzFltMSxJpacNki96+WIcX5s/vum+ckXiLYg== +esbuild-darwin-64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.54.tgz#24ba67b9a8cb890a3c08d9018f887cc221cdda25" + integrity sha512-jtdKWV3nBviOd5v4hOpkVmpxsBy90CGzebpbO9beiqUYVMBtSc0AL9zGftFuBon7PNDcdvNCEuQqw2x0wP9yug== -esbuild-darwin-arm64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.49.tgz#c04a3a57dad94a972c66a697a68a25aa25947f41" - integrity sha512-XMaqDxO846srnGlUSJnwbijV29MTKUATmOLyQSfswbK/2X5Uv28M9tTLUJcKKxzoo9lnkYPsx2o8EJcTYwCs/A== +esbuild-darwin-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.54.tgz#3f7cdb78888ee05e488d250a2bdaab1fa671bf73" + integrity sha512-OPafJHD2oUPyvJMrsCvDGkRrVCar5aVyHfWGQzY1dWnzErjrDuSETxwA2HSsyg2jORLY8yBfzc1MIpUkXlctmw== -esbuild-freebsd-64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.49.tgz#c404dbd66c98451395b1eef0fa38b73030a7be82" - integrity sha512-NJ5Q6AjV879mOHFri+5lZLTp5XsO2hQ+KSJYLbfY9DgCu8s6/Zl2prWXVANYTeCDLlrIlNNYw8y34xqyLDKOmQ== +esbuild-freebsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.54.tgz#09250f997a56ed4650f3e1979c905ffc40bbe94d" + integrity sha512-OKwd4gmwHqOTp4mOGZKe/XUlbDJ4Q9TjX0hMPIDBUWWu/kwhBAudJdBoxnjNf9ocIB6GN6CPowYpR/hRCbSYAg== -esbuild-freebsd-arm64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.49.tgz#b62cec96138ebc5937240ce3e1b97902963ea74a" - integrity sha512-lFLtgXnAc3eXYqj5koPlBZvEbBSOSUbWO3gyY/0+4lBdRqELyz4bAuamHvmvHW5swJYL7kngzIZw6kdu25KGOA== +esbuild-freebsd-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.54.tgz#bafb46ed04fc5f97cbdb016d86947a79579f8e48" + integrity sha512-sFwueGr7OvIFiQT6WeG0jRLjkjdqWWSrfbVwZp8iMP+8UHEHRBvlaxL6IuKNDwAozNUmbb8nIMXa7oAOARGs1Q== -esbuild-linux-32@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.49.tgz#495b1cc011b8c64d8bbaf65509c1e7135eb9ddbf" - integrity sha512-zTTH4gr2Kb8u4QcOpTDVn7Z8q7QEIvFl/+vHrI3cF6XOJS7iEI1FWslTo3uofB2+mn6sIJEQD9PrNZKoAAMDiA== +esbuild-linux-32@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.54.tgz#e2a8c4a8efdc355405325033fcebeb941f781fe5" + integrity sha512-1ZuY+JDI//WmklKlBgJnglpUL1owm2OX+8E1syCD6UAxcMM/XoWd76OHSjl/0MR0LisSAXDqgjT3uJqT67O3qw== -esbuild-linux-64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.49.tgz#3f28dd8f986e6ff42f38888ee435a9b1fb916a56" - integrity sha512-hYmzRIDzFfLrB5c1SknkxzM8LdEUOusp6M2TnuQZJLRtxTgyPnZZVtyMeCLki0wKgYPXkFsAVhi8vzo2mBNeTg== +esbuild-linux-64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.54.tgz#de5fdba1c95666cf72369f52b40b03be71226652" + integrity sha512-EgjAgH5HwTbtNsTqQOXWApBaPVdDn7XcK+/PtJwZLT1UmpLoznPd8c5CxqsH2dQK3j05YsB3L17T8vE7cp4cCg== -esbuild-linux-arm64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.49.tgz#a52e99ae30246566dc5f33e835aa6ca98ef70e33" - integrity sha512-KLQ+WpeuY+7bxukxLz5VgkAAVQxUv67Ft4DmHIPIW+2w3ObBPQhqNoeQUHxopoW/aiOn3m99NSmSV+bs4BSsdA== +esbuild-linux-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.54.tgz#dae4cd42ae9787468b6a5c158da4c84e83b0ce8b" + integrity sha512-WL71L+0Rwv+Gv/HTmxTEmpv0UgmxYa5ftZILVi2QmZBgX3q7+tDeOQNqGtdXSdsL8TQi1vIaVFHUPDe0O0kdig== -esbuild-linux-arm@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.49.tgz#7c33d05a64ec540cf7474834adaa57b3167bbe97" - integrity sha512-iE3e+ZVv1Qz1Sy0gifIsarJMQ89Rpm9mtLSRtG3AH0FPgAzQ5Z5oU6vYzhc/3gSPi2UxdCOfRhw2onXuFw/0lg== +esbuild-linux-arm@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.54.tgz#a2c1dff6d0f21dbe8fc6998a122675533ddfcd59" + integrity sha512-qqz/SjemQhVMTnvcLGoLOdFpCYbz4v4fUo+TfsWG+1aOu70/80RV6bgNpR2JCrppV2moUQkww+6bWxXRL9YMGw== -esbuild-linux-mips64le@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.49.tgz#ed062bd844b587be649443831eb84ba304685f25" - integrity sha512-n+rGODfm8RSum5pFIqFQVQpYBw+AztL8s6o9kfx7tjfK0yIGF6tm5HlG6aRjodiiKkH2xAiIM+U4xtQVZYU4rA== +esbuild-linux-mips64le@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.54.tgz#d9918e9e4cb972f8d6dae8e8655bf9ee131eda34" + integrity sha512-qTHGQB8D1etd0u1+sB6p0ikLKRVuCWhYQhAHRPkO+OF3I/iSlTKNNS0Lh2Oc0g0UFGguaFZZiPJdJey3AGpAlw== -esbuild-linux-ppc64le@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.49.tgz#c0786fb5bddffd90c10a2078181513cbaf077958" - integrity sha512-WP9zR4HX6iCBmMFH+XHHng2LmdoIeUmBpL4aL2TR8ruzXyT4dWrJ5BSbT8iNo6THN8lod6GOmYDLq/dgZLalGw== +esbuild-linux-ppc64le@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.54.tgz#3f9a0f6d41073fb1a640680845c7de52995f137e" + integrity sha512-j3OMlzHiqwZBDPRCDFKcx595XVfOfOnv68Ax3U4UKZ3MTYQB5Yz3X1mn5GnodEVYzhtZgxEBidLWeIs8FDSfrQ== -esbuild-linux-riscv64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.49.tgz#579b0e7cc6fce4bfc698e991a52503bb616bec49" - integrity sha512-h66ORBz+Dg+1KgLvzTVQEA1LX4XBd1SK0Fgbhhw4akpG/YkN8pS6OzYI/7SGENiN6ao5hETRDSkVcvU9NRtkMQ== +esbuild-linux-riscv64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.54.tgz#618853c028178a61837bc799d2013d4695e451c8" + integrity sha512-y7Vt7Wl9dkOGZjxQZnDAqqn+XOqFD7IMWiewY5SPlNlzMX39ocPQlOaoxvT4FllA5viyV26/QzHtvTjVNOxHZg== -esbuild-linux-s390x@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.49.tgz#09eb15c753e249a500b4e28d07c5eef7524a9740" - integrity sha512-DhrUoFVWD+XmKO1y7e4kNCqQHPs6twz6VV6Uezl/XHYGzM60rBewBF5jlZjG0nCk5W/Xy6y1xWeopkrhFFM0sQ== +esbuild-linux-s390x@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.54.tgz#d1885c4c5a76bbb5a0fe182e2c8c60eb9e29f2a6" + integrity sha512-zaHpW9dziAsi7lRcyV4r8dhfG1qBidQWUXweUjnw+lliChJqQr+6XD71K41oEIC3Mx1KStovEmlzm+MkGZHnHA== esbuild-loader@^2.18.0: version "2.19.0" @@ -12136,61 +12629,62 @@ esbuild-loader@^2.18.0: tapable "^2.2.0" webpack-sources "^2.2.0" -esbuild-netbsd-64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.49.tgz#f7337cd2bddb7cc9d100d19156f36c9ca117b58d" - integrity sha512-BXaUwFOfCy2T+hABtiPUIpWjAeWK9P8O41gR4Pg73hpzoygVGnj0nI3YK4SJhe52ELgtdgWP/ckIkbn2XaTxjQ== +esbuild-netbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.54.tgz#69ae917a2ff241b7df1dbf22baf04bd330349e81" + integrity sha512-PR01lmIMnfJTgeU9VJTDY9ZerDWVFIUzAtJuDHwwceppW7cQWjBBqP48NdeRtoP04/AtO9a7w3viI+PIDr6d+w== -esbuild-openbsd-64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.49.tgz#1f8bdc49f8a44396e73950a3fb6b39828563631d" - integrity sha512-lP06UQeLDGmVPw9Rg437Btu6J9/BmyhdoefnQ4gDEJTtJvKtQaUcOQrhjTq455ouZN4EHFH1h28WOJVANK41kA== +esbuild-openbsd-64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.54.tgz#db4c8495287a350a6790de22edea247a57c5d47b" + integrity sha512-Qyk7ikT2o7Wu76UsvvDS5q0amJvmRzDyVlL0qf5VLsLchjCa1+IAvd8kTBgUxD7VBUUVgItLkk609ZHUc1oCaw== -esbuild-sunos-64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.49.tgz#47d042739365b61aa8ca642adb69534a8eef9f7a" - integrity sha512-4c8Zowp+V3zIWje329BeLbGh6XI9c/rqARNaj5yPHdC61pHI9UNdDxT3rePPJeWcEZVKjkiAS6AP6kiITp7FSw== +esbuild-sunos-64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.54.tgz#54287ee3da73d3844b721c21bc80c1dc7e1bf7da" + integrity sha512-28GZ24KmMSeKi5ueWzMcco6EBHStL3B6ubM7M51RmPwXQGLe0teBGJocmWhgwccA1GeFXqxzILIxXpHbl9Q/Kw== -esbuild-windows-32@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.49.tgz#79198c88ec9bde163c18a6b430c34eab098ec21a" - integrity sha512-q7Rb+J9yHTeKr9QTPDYkqfkEj8/kcKz9lOabDuvEXpXuIcosWCJgo5Z7h/L4r7rbtTH4a8U2FGKb6s1eeOHmJA== +esbuild-windows-32@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.54.tgz#f8aaf9a5667630b40f0fb3aa37bf01bbd340ce31" + integrity sha512-T+rdZW19ql9MjS7pixmZYVObd9G7kcaZo+sETqNH4RCkuuYSuv9AGHUVnPoP9hhuE1WM1ZimHz1CIBHBboLU7w== -esbuild-windows-64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.49.tgz#b36b230d18d1ee54008e08814c4799c7806e8c79" - integrity sha512-+Cme7Ongv0UIUTniPqfTX6mJ8Deo7VXw9xN0yJEN1lQMHDppTNmKwAM3oGbD/Vqff+07K2gN0WfNkMohmG+dVw== +esbuild-windows-64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.54.tgz#bf54b51bd3e9b0f1886ffdb224a4176031ea0af4" + integrity sha512-AoHTRBUuYwXtZhjXZbA1pGfTo8cJo3vZIcWGLiUcTNgHpJJMC1rVA44ZereBHMJtotyN71S8Qw0npiCIkW96cQ== -esbuild-windows-arm64@0.14.49: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.49.tgz#d83c03ff6436caf3262347cfa7e16b0a8049fae7" - integrity sha512-v+HYNAXzuANrCbbLFJ5nmO3m5y2PGZWLe3uloAkLt87aXiO2mZr3BTmacZdjwNkNEHuH3bNtN8cak+mzVjVPfA== +esbuild-windows-arm64@0.14.54: + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.54.tgz#937d15675a15e4b0e4fafdbaa3a01a776a2be982" + integrity sha512-M0kuUvXhot1zOISQGXwWn6YtS+Y/1RT9WrVIOywZnJHo3jCDyewAc79aKNQWFCQm+xNHVTq9h8dZKvygoXQQRg== esbuild@^0.14.1, esbuild@^0.14.10, esbuild@^0.14.39: - version "0.14.49" - resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.14.49.tgz#b82834760eba2ddc17b44f05cfcc0aaca2bae492" - integrity sha512-/TlVHhOaq7Yz8N1OJrjqM3Auzo5wjvHFLk+T8pIue+fhnhIMpfAzsG6PLVMbFveVxqD2WOp3QHei+52IMUNmCw== + version "0.14.54" + resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.14.54.tgz#8b44dcf2b0f1a66fc22459943dccf477535e9aa2" + integrity sha512-Cy9llcy8DvET5uznocPyqL3BFRrFXSVqbgpMJ9Wz8oVjZlh/zUSNbPRbov0VX7VxN2JH1Oa0uNxZ7eLRb62pJA== optionalDependencies: - esbuild-android-64 "0.14.49" - esbuild-android-arm64 "0.14.49" - esbuild-darwin-64 "0.14.49" - esbuild-darwin-arm64 "0.14.49" - esbuild-freebsd-64 "0.14.49" - esbuild-freebsd-arm64 "0.14.49" - esbuild-linux-32 "0.14.49" - esbuild-linux-64 "0.14.49" - esbuild-linux-arm "0.14.49" - esbuild-linux-arm64 "0.14.49" - esbuild-linux-mips64le "0.14.49" - esbuild-linux-ppc64le "0.14.49" - esbuild-linux-riscv64 "0.14.49" - esbuild-linux-s390x "0.14.49" - esbuild-netbsd-64 "0.14.49" - esbuild-openbsd-64 "0.14.49" - esbuild-sunos-64 "0.14.49" - esbuild-windows-32 "0.14.49" - esbuild-windows-64 "0.14.49" - esbuild-windows-arm64 "0.14.49" + "@esbuild/linux-loong64" "0.14.54" + esbuild-android-64 "0.14.54" + esbuild-android-arm64 "0.14.54" + esbuild-darwin-64 "0.14.54" + esbuild-darwin-arm64 "0.14.54" + esbuild-freebsd-64 "0.14.54" + esbuild-freebsd-arm64 "0.14.54" + esbuild-linux-32 "0.14.54" + esbuild-linux-64 "0.14.54" + esbuild-linux-arm "0.14.54" + esbuild-linux-arm64 "0.14.54" + esbuild-linux-mips64le "0.14.54" + esbuild-linux-ppc64le "0.14.54" + esbuild-linux-riscv64 "0.14.54" + esbuild-linux-s390x "0.14.54" + esbuild-netbsd-64 "0.14.54" + esbuild-openbsd-64 "0.14.54" + esbuild-sunos-64 "0.14.54" + esbuild-windows-32 "0.14.54" + esbuild-windows-64 "0.14.54" + esbuild-windows-arm64 "0.14.54" escalade@^3.1.1: version "3.1.1" @@ -12302,27 +12796,27 @@ eslint-plugin-import@^2.25.4: tsconfig-paths "^3.14.1" eslint-plugin-jest@^26.1.2: - version "26.6.0" - resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.6.0.tgz#546804fa42da75d7d58d4d3b278d5186abd3f6c0" - integrity sha512-f8n46/97ZFdU4KqeQYqO8AEVGIhHWvkpgNBWHH3jrM28/y8llnbf3IjfIKv6p2pZIMinK1PCqbbROxs9Eud02Q== + version "26.8.7" + resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.8.7.tgz#f38f067d0a69483d64578eb43508ca7b29c8a4b7" + integrity sha512-nJJVv3VY6ZZvJGDMC8h1jN/TIGT4We1JkNn1lvstPURicr/eZPVnlFULQ4W2qL9ByCuCr1hPmlBOc2aZ1ktw4Q== dependencies: "@typescript-eslint/utils" "^5.10.0" eslint-plugin-jsx-a11y@^6.5.1: - version "6.6.0" - resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.0.tgz#2c5ac12e013eb98337b9aa261c3b355275cc6415" - integrity sha512-kTeLuIzpNhXL2CwLlc8AHI0aFRwWHcg483yepO9VQiHzM9bZwJdzTkzBszbuPrbgGmq2rlX/FaT2fJQsjUSHsw== + version "6.6.1" + resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz#93736fc91b83fdc38cc8d115deedfc3091aef1ff" + integrity sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q== dependencies: - "@babel/runtime" "^7.18.3" + "@babel/runtime" "^7.18.9" aria-query "^4.2.2" array-includes "^3.1.5" ast-types-flow "^0.0.7" - axe-core "^4.4.2" + axe-core "^4.4.3" axobject-query "^2.2.0" damerau-levenshtein "^1.0.8" emoji-regex "^9.2.2" has "^1.0.3" - jsx-ast-utils "^3.3.1" + jsx-ast-utils "^3.3.2" language-tags "^1.0.5" minimatch "^3.1.2" semver "^6.3.0" @@ -12419,12 +12913,13 @@ eslint-webpack-plugin@^3.1.1: schema-utils "^4.0.0" eslint@^8.6.0: - version "8.19.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.19.0.tgz#7342a3cbc4fbc5c106a1eefe0fd0b50b6b1a7d28" - integrity sha512-SXOPj3x9VKvPe81TjjUJCYlV4oJjQw68Uek+AM0X4p+33dj2HY5bpTZOgnQHcG2eAm1mtCU9uNMnJi7exU/kYw== + version "8.22.0" + resolved "https://registry.npmjs.org/eslint/-/eslint-8.22.0.tgz#78fcb044196dfa7eef30a9d65944f6f980402c48" + integrity sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA== dependencies: "@eslint/eslintrc" "^1.3.0" - "@humanwhocodes/config-array" "^0.9.2" + "@humanwhocodes/config-array" "^0.10.4" + "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" ajv "^6.10.0" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -12434,14 +12929,17 @@ eslint@^8.6.0: eslint-scope "^7.1.1" eslint-utils "^3.0.0" eslint-visitor-keys "^3.3.0" - espree "^9.3.2" + espree "^9.3.3" esquery "^1.4.0" esutils "^2.0.2" fast-deep-equal "^3.1.3" file-entry-cache "^6.0.1" + find-up "^5.0.0" functional-red-black-tree "^1.0.1" glob-parent "^6.0.1" globals "^13.15.0" + globby "^11.1.0" + grapheme-splitter "^1.0.4" ignore "^5.2.0" import-fresh "^3.0.0" imurmurhash "^0.1.4" @@ -12473,6 +12971,15 @@ espree@^9.3.2: acorn-jsx "^5.3.2" eslint-visitor-keys "^3.3.0" +espree@^9.3.3: + version "9.3.3" + resolved "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d" + integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" + esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -12545,6 +13052,11 @@ event-stream@=3.3.4: stream-combiner "~0.0.4" through "~2.3.1" +event-target-polyfill@^0.0.3: + version "0.0.3" + resolved "https://registry.npmjs.org/event-target-polyfill/-/event-target-polyfill-0.0.3.tgz#ed373295f3b257774b5d75afb2599331d9f3406c" + integrity sha512-ZMc6UuvmbinrCk4RzGyVmRyIsAyxMRlp4CqSrcQRO8Dy0A9ldbiRy5kdtBj4OtP7EClGdqGfIqo9JmOClMsGLQ== + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" @@ -12555,6 +13067,11 @@ eventemitter2@^6.4.3, eventemitter2@^6.4.4: resolved "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.5.tgz#97380f758ae24ac15df8353e0cc27f8b95644655" integrity sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw== +eventemitter3@^3.1.0: + version "3.1.2" + resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" + integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q== + eventemitter3@^4.0.0, eventemitter3@^4.0.1, eventemitter3@^4.0.4: version "4.0.7" resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -12579,63 +13096,63 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: safe-buffer "^5.1.1" "example-app@link:packages/app": - version "0.2.73-next.3" + version "0.2.74" dependencies: - "@backstage/app-defaults" "^1.0.4-next.3" - "@backstage/catalog-model" "^1.1.0-next.3" - "@backstage/cli" "^0.18.0-next.3" + "@backstage/app-defaults" "^1.0.5" + "@backstage/catalog-model" "^1.1.0" + "@backstage/cli" "^0.18.1" "@backstage/config" "^1.0.1" - "@backstage/core-app-api" "^1.0.4-next.1" - "@backstage/core-components" "^0.10.0-next.3" - "@backstage/core-plugin-api" "^1.0.4-next.0" - "@backstage/integration-react" "^1.1.2-next.3" - "@backstage/plugin-airbrake" "^0.3.7-next.3" - "@backstage/plugin-apache-airflow" "^0.2.0-next.3" - "@backstage/plugin-api-docs" "^0.8.7-next.3" - "@backstage/plugin-azure-devops" "^0.1.23-next.3" - "@backstage/plugin-badges" "^0.2.31-next.3" - "@backstage/plugin-catalog" "^1.4.0-next.3" - "@backstage/plugin-catalog-common" "^1.0.4-next.0" - "@backstage/plugin-catalog-graph" "^0.2.19-next.3" - "@backstage/plugin-catalog-import" "^0.8.10-next.3" - "@backstage/plugin-catalog-react" "^1.1.2-next.3" - "@backstage/plugin-circleci" "^0.3.7-next.3" - "@backstage/plugin-cloudbuild" "^0.3.7-next.3" - "@backstage/plugin-code-coverage" "^0.2.0-next.3" - "@backstage/plugin-cost-insights" "^0.11.29-next.3" - "@backstage/plugin-dynatrace" "^0.1.1-next.3" - "@backstage/plugin-explore" "^0.3.38-next.3" - "@backstage/plugin-gcalendar" "^0.3.3-next.3" - "@backstage/plugin-gcp-projects" "^0.3.26-next.3" - "@backstage/plugin-github-actions" "^0.5.7-next.3" - "@backstage/plugin-gocd" "^0.1.13-next.3" - "@backstage/plugin-graphiql" "^0.2.39-next.3" - "@backstage/plugin-home" "^0.4.23-next.3" - "@backstage/plugin-jenkins" "^0.7.6-next.3" - "@backstage/plugin-kafka" "^0.3.7-next.3" - "@backstage/plugin-kubernetes" "^0.7.0-next.3" - "@backstage/plugin-lighthouse" "^0.3.7-next.3" - "@backstage/plugin-newrelic" "^0.3.25-next.3" - "@backstage/plugin-newrelic-dashboard" "^0.2.0-next.3" - "@backstage/plugin-org" "^0.5.7-next.3" - "@backstage/plugin-pagerduty" "0.5.0-next.3" - "@backstage/plugin-permission-react" "^0.4.3-next.1" - "@backstage/plugin-rollbar" "^0.4.7-next.3" - "@backstage/plugin-scaffolder" "^1.4.0-next.3" - "@backstage/plugin-search" "^0.9.1-next.3" - "@backstage/plugin-search-common" "^0.3.6-next.0" - "@backstage/plugin-search-react" "^0.2.2-next.3" - "@backstage/plugin-sentry" "^0.4.0-next.3" - "@backstage/plugin-shortcuts" "^0.2.8-next.3" - "@backstage/plugin-stack-overflow" "^0.1.3-next.3" - "@backstage/plugin-tech-insights" "^0.2.3-next.3" - "@backstage/plugin-tech-radar" "^0.5.14-next.3" - "@backstage/plugin-techdocs" "^1.2.1-next.3" - "@backstage/plugin-techdocs-module-addons-contrib" "^1.0.2-next.3" - "@backstage/plugin-techdocs-react" "^1.0.2-next.2" - "@backstage/plugin-todo" "^0.2.9-next.3" - "@backstage/plugin-user-settings" "^0.4.6-next.3" - "@backstage/theme" "^0.2.16-next.1" + "@backstage/core-app-api" "^1.0.5" + "@backstage/core-components" "^0.11.0" + "@backstage/core-plugin-api" "^1.0.5" + "@backstage/integration-react" "^1.1.3" + "@backstage/plugin-airbrake" "^0.3.8" + "@backstage/plugin-apache-airflow" "^0.2.1" + "@backstage/plugin-api-docs" "^0.8.8" + "@backstage/plugin-azure-devops" "^0.1.24" + "@backstage/plugin-badges" "^0.2.32" + "@backstage/plugin-catalog-common" "^1.0.5" + "@backstage/plugin-catalog-graph" "^0.2.20" + "@backstage/plugin-catalog-import" "^0.8.11" + "@backstage/plugin-catalog-react" "^1.1.3" + "@backstage/plugin-circleci" "^0.3.8" + "@backstage/plugin-cloudbuild" "^0.3.8" + "@backstage/plugin-code-coverage" "^0.2.1" + "@backstage/plugin-cost-insights" "^0.11.30" + "@backstage/plugin-dynatrace" "^0.1.2" + "@backstage/plugin-explore" "^0.3.39" + "@backstage/plugin-gcalendar" "^0.3.4" + "@backstage/plugin-gcp-projects" "^0.3.27" + "@backstage/plugin-github-actions" "^0.5.8" + "@backstage/plugin-gocd" "^0.1.14" + "@backstage/plugin-graphiql" "^0.2.40" + "@backstage/plugin-home" "^0.4.24" + "@backstage/plugin-jenkins" "^0.7.7" + "@backstage/plugin-kafka" "^0.3.8" + "@backstage/plugin-kubernetes" "^0.7.1" + "@backstage/plugin-lighthouse" "^0.3.8" + "@backstage/plugin-newrelic" "^0.3.26" + "@backstage/plugin-newrelic-dashboard" "^0.2.1" + "@backstage/plugin-org" "^0.5.8" + "@backstage/plugin-pagerduty" "0.5.1" + "@backstage/plugin-permission-react" "^0.4.4" + "@backstage/plugin-rollbar" "^0.4.8" + "@backstage/plugin-scaffolder" "^1.5.0" + "@backstage/plugin-search" "^1.0.1" + "@backstage/plugin-search-common" "^1.0.0" + "@backstage/plugin-search-react" "^1.0.1" + "@backstage/plugin-sentry" "^0.4.1" + "@backstage/plugin-shortcuts" "^0.3.0" + "@backstage/plugin-stack-overflow" "^0.1.4" + "@backstage/plugin-tech-insights" "^0.2.4" + "@backstage/plugin-tech-radar" "^0.5.15" + "@backstage/plugin-techdocs" "^1.3.1" + "@backstage/plugin-techdocs-module-addons-contrib" "^1.0.3" + "@backstage/plugin-techdocs-react" "^1.0.3" + "@backstage/plugin-todo" "^0.2.10" + "@backstage/plugin-user-settings" "^0.4.7" + "@backstage/theme" "^0.2.16" + "@internal/plugin-catalog-customized" "0.0.1" "@material-ui/core" "^4.12.2" "@material-ui/icons" "^4.9.1" "@material-ui/lab" "4.0.0-alpha.57" @@ -12699,19 +13216,6 @@ execa@5.1.1, execa@^5.0.0: signal-exit "^3.0.3" strip-final-newline "^2.0.0" -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - execa@^6.1.0: version "6.1.0" resolved "https://registry.npmjs.org/execa/-/execa-6.1.0.tgz#cea16dee211ff011246556388effa0818394fb20" @@ -13306,9 +13810,9 @@ fork-ts-checker-webpack-plugin@^6.5.0: tapable "^1.0.0" fork-ts-checker-webpack-plugin@^7.0.0-alpha.8: - version "7.2.12" - resolved "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.12.tgz#d15c48745f9092574b41138934aa3de504a39ba1" - integrity sha512-SCjmmjPXPgp5XRQ49hXd2Eqth8rz4+ggtOHygTzyaOn32oIIOd8Kw+xKcgXNkFGlZy5l03bHRYTkbQs+TWhaNA== + version "7.2.13" + resolved "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.2.13.tgz#51ffd6a2f96f03ab64b92f8aedf305dbf3dee0f1" + integrity sha512-fR3WRkOb4bQdWB/y7ssDUlVdrclvwtyCUIHCfivAoYxq9dF7XfrDKbMdZIfwJ7hxIAqkYSGeU7lLJE6xrxIBdg== dependencies: "@babel/code-frame" "^7.16.7" chalk "^4.1.2" @@ -13318,6 +13822,7 @@ fork-ts-checker-webpack-plugin@^7.0.0-alpha.8: fs-extra "^10.0.0" memfs "^3.4.1" minimatch "^3.0.4" + node-abort-controller "^3.0.1" schema-utils "^3.1.1" semver "^7.3.5" tapable "^2.2.1" @@ -13502,16 +14007,6 @@ fsevents@^2.3.2, fsevents@~2.3.2: resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -fstream@^1.0.12: - version "1.0.12" - resolved "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" - integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - function-bind@^1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -13617,14 +14112,6 @@ gaxios@^5.0.0: is-stream "^2.0.0" node-fetch "^2.6.7" -gcp-metadata@^4.2.0: - version "4.2.1" - resolved "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz#31849fbcf9025ef34c2297c32a89a1e7e9f2cd62" - integrity sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw== - dependencies: - gaxios "^4.0.0" - json-bigint "^1.0.0" - gcp-metadata@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-5.0.0.tgz#a00f999f60a4461401e7c515f8a3267cfb401ee7" @@ -13712,13 +14199,6 @@ get-stdin@^8.0.0: resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - get-stream@^5.0.0, get-stream@^5.1.0: version "5.1.0" resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" @@ -13806,7 +14286,7 @@ git-up@^6.0.0: is-ssh "^1.4.0" parse-url "^7.0.2" -git-url-parse@^11.4.4, git-url-parse@^11.6.0: +git-url-parse@^11.4.4: version "11.6.0" resolved "https://registry.npmjs.org/git-url-parse/-/git-url-parse-11.6.0.tgz#c634b8de7faa66498a2b88932df31702c67df605" integrity sha512-WWUxvJs5HsyHL6L08wOusa/IXYtMuCAhrMmnTjQPpBU0TTHyDhnOATNH3xNQz7YOQUsqIIPTGr4xiVti1Hsk5g== @@ -13973,25 +14453,10 @@ globby@^7.1.1: pify "^3.0.0" slash "^1.0.0" -google-auth-library@^7.14.0: - version "7.14.1" - resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz#e3483034162f24cc71b95c8a55a210008826213c" - integrity sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA== - dependencies: - arrify "^2.0.0" - base64-js "^1.3.0" - ecdsa-sig-formatter "^1.0.11" - fast-text-encoding "^1.0.0" - gaxios "^4.0.0" - gcp-metadata "^4.2.0" - gtoken "^5.0.4" - jws "^4.0.0" - lru-cache "^6.0.0" - google-auth-library@^8.0.0, google-auth-library@^8.0.1, google-auth-library@^8.0.2: - version "8.1.1" - resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.1.1.tgz#4068d2b1512b812d3d3dfbdc848452a0d5a550de" - integrity sha512-eG3pCfrLgVJe19KhAeZwW0m1LplNEo0FX1GboWf3hu18zD2jq8TUH2K8900AB2YRAuJ7A+1aSXDp1BODjwwRzg== + version "8.3.0" + resolved "https://registry.npmjs.org/google-auth-library/-/google-auth-library-8.3.0.tgz#9286a613ee089f1d1728c07b9a302a22acf2dc2a" + integrity sha512-rXasaUScggvyD5ELpQC7SIOUOdqyOIifCK9TRDOLFEcuw1JxuyewKAwDs2QiKzMf8uLa0L360W0bVlV+sJDc8g== dependencies: arrify "^2.0.0" base64-js "^1.3.0" @@ -14003,25 +14468,6 @@ google-auth-library@^8.0.0, google-auth-library@^8.0.1, google-auth-library@^8.0 jws "^4.0.0" lru-cache "^6.0.0" -google-gax@^2.24.1: - version "2.30.5" - resolved "https://registry.npmjs.org/google-gax/-/google-gax-2.30.5.tgz#e836f984f3228900a8336f608c83d75f9cb73eff" - integrity sha512-Jey13YrAN2hfpozHzbtrwEfEHdStJh1GwaQ2+Akh1k0Tv/EuNVSuBtHZoKSBm5wBMvNsxTsEIZ/152NrYyZgxQ== - dependencies: - "@grpc/grpc-js" "~1.6.0" - "@grpc/proto-loader" "^0.6.12" - "@types/long" "^4.0.0" - abort-controller "^3.0.0" - duplexify "^4.0.0" - fast-text-encoding "^1.0.3" - google-auth-library "^7.14.0" - is-stream-ended "^0.1.4" - node-fetch "^2.6.1" - object-hash "^3.0.0" - proto3-json-serializer "^0.1.8" - protobufjs "6.11.3" - retry-request "^4.0.0" - google-gax@^3.0.1: version "3.0.3" resolved "https://registry.npmjs.org/google-gax/-/google-gax-3.0.3.tgz#c8f75dc0ec044fc8ecf97675d85b77911539cca5" @@ -14041,13 +14487,6 @@ google-gax@^3.0.1: protobufjs "6.11.3" retry-request "^5.0.0" -google-p12-pem@^3.0.3: - version "3.1.3" - resolved "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.3.tgz#5497998798ee86c2fc1f4bb1f92b7729baf37537" - integrity sha512-MC0jISvzymxePDVembypNefkAQp+DRP7dBE+zNUPaIjEspIlYg0++OrsNr248V9tPbz6iqtZ7rX1hxWA5B8qBQ== - dependencies: - node-forge "^1.0.0" - google-p12-pem@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-4.0.0.tgz#f46581add1dc6ea0b96160cda6ce37ee35ab8ca3" @@ -14077,7 +14516,7 @@ got@^11.8.3: p-cancelable "^2.0.0" responselike "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.9" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== @@ -14093,12 +14532,12 @@ grapheme-splitter@^1.0.4: integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== graphiql@^1.5.12, graphiql@^1.8.8: - version "1.9.13" - resolved "https://registry.npmjs.org/graphiql/-/graphiql-1.9.13.tgz#f379425b407bad6eec4aa36a2e38d764a2c13b25" - integrity sha512-w/kFnK0N8ooN07vw5dKcDZ4CAmRfkjkTQbSj6LkEigJB/yTZ92r2QA/XROGlff0xn4r6aWfHjRp5AMrND4dLZg== + version "1.11.5" + resolved "https://registry.npmjs.org/graphiql/-/graphiql-1.11.5.tgz#daf0de27b704f17c9d87ce56eea0fdcd7a370269" + integrity sha512-NI92XdSVwXTsqzJc6ykaAkKVMeC8IRRp3XzkxVQwtqDsZlVKtR2ZnssXNYt05TMGbi1ehoipn9tFywVohOlHjg== dependencies: - "@graphiql/react" "^0.5.2" - "@graphiql/toolkit" "^0.6.0" + "@graphiql/react" "^0.10.0" + "@graphiql/toolkit" "^0.6.1" entities "^2.0.0" graphql-language-service "^5.0.6" markdown-it "^12.2.0" @@ -14171,15 +14610,15 @@ graphql-type-json@^0.3.2: resolved "https://registry.npmjs.org/graphql-type-json/-/graphql-type-json-0.3.2.tgz#f53a851dbfe07bd1c8157d24150064baab41e115" integrity sha512-J+vjof74oMlCWXSvt0DOf2APEdZOCdubEvGDUAlqH//VBYcOYsGgRW7Xzorr44LvkjiuvecWc8fChxuZZbChtg== -graphql-ws@^5.4.1: - version "5.9.1" - resolved "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.9.1.tgz#9c0fa48ceb695d61d574ed3ab21b426729e87f2d" - integrity sha512-mL/SWGBwIT9Meq0NlfS55yXXTOeWPMbK7bZBEZhFu46bcGk1coTx2Sdtzxdk+9yHWngD+Fk1PZDWaAutQa9tpw== +graphql-ws@^5.4.1, graphql-ws@^5.9.0: + version "5.10.1" + resolved "https://registry.npmjs.org/graphql-ws/-/graphql-ws-5.10.1.tgz#c5402a62f1be13e244ab90a6306b94f643577312" + integrity sha512-MKm/3SRd1vj5Km8NaujsgeGRTKZQjUN5HRnIMJ8dL2UznKoxvrtQyJqTmqJt0f6vQd9AooDg/+baXo3huiY4Ew== graphql@^16.0.0, graphql@^16.3.0: - version "16.5.0" - resolved "https://registry.npmjs.org/graphql/-/graphql-16.5.0.tgz#41b5c1182eaac7f3d47164fb247f61e4dfb69c85" - integrity sha512-qbHgh8Ix+j/qY+a/ZcJnFQ+j8ezakqPiHwPiZhV/3PgGlgf96QMBB5/f2rkiC9sgLoy/xvT6TSiaf2nTHJh5iA== + version "16.6.0" + resolved "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz#c2dcffa4649db149f6282af726c8c83f1c7c5fdb" + integrity sha512-KPIBPDlW7NxrbT/eh4qPXz5FiFdL5UbaA0XUNz2Rp3Z3hqBSkbj0GVjwFDztsWVauZUWsbKHgMg++sk8UX0bkw== grouped-queue@^2.0.0: version "2.0.0" @@ -14206,15 +14645,24 @@ grpc-docs@^1.0.6, grpc-docs@^1.1.2: rollup-plugin-smart-asset "^2.1.2" styled-components "^5.3.3" -gtoken@^5.0.4: +gson-conform@^1.0.3: + version "1.0.3" + resolved "https://registry.npmjs.org/gson-conform/-/gson-conform-1.0.3.tgz#6f982f98ea84199280bd48b6bfbcd0ae7447f1e2" + integrity sha512-gaZQN/5ZbohkLBOs4JKHkg/IdOB9kuuEr5SVLAjHUs+Q+Nl746DRe18GgQy4oxxVXStO//Zga2wg4eWL9Mfshw== + +gson-pointer@4.1.1, gson-pointer@^4.1.1: + version "4.1.1" + resolved "https://registry.npmjs.org/gson-pointer/-/gson-pointer-4.1.1.tgz#088d6aa38d52753530288d13b5a75b6a43170e9b" + integrity sha512-rOS/zCLUI8BT0+/U+p5nzI0RfhIyRmzkpwzyCj8gcLoRl3rHuysk6ci1IQ955AQQZDSNN3mVec26Sx9wRZ0EjA== + +gson-query@^5.1.0: version "5.1.0" - resolved "https://registry.npmjs.org/gtoken/-/gtoken-5.1.0.tgz#4ba8d2fc9a8459098f76e7e8fd7beaa39fda9fe4" - integrity sha512-4d8N6Lk8TEAHl9vVoRVMh9BNOKWVgl2DdNtr3428O75r3QFrF/a5MMu851VmK0AA8+iSvbwRv69k5XnMLURGhg== + resolved "https://registry.npmjs.org/gson-query/-/gson-query-5.1.0.tgz#8f34a062849f8c08be0c35eddaa2ad18a4326a49" + integrity sha512-xKb/90XfmLLKGgX8Y7LRF4yKnMR/ckV5WOQ/Ip0pRXuDh7jUhdY1UYjPvQnF7/UMbNsAo0168j2j0yt9+4QdaA== dependencies: - gaxios "^4.0.0" - google-p12-pem "^3.0.3" - jws "^4.0.0" - mime "^2.2.0" + ebnf "^1.9.0" + gson-conform "^1.0.3" + gson-pointer "4.1.1" gtoken@^6.0.0: version "6.0.1" @@ -14422,9 +14870,9 @@ headers-polyfill@^3.0.4: integrity sha512-JoLCAdCEab58+2/yEmSnOlficyHFpIl0XJqwu3l+Unkm1gXpFUYsThz6Yha3D6tNhocWkCPfyW0YVIGWFqTi7w== helmet@^5.0.2: - version "5.1.0" - resolved "https://registry.npmjs.org/helmet/-/helmet-5.1.0.tgz#e98a5d4bf89ab8119c856018a3bcc82addadcd47" - integrity sha512-klsunXs8rgNSZoaUrNeuCiWUxyc+wzucnEnFejUg3/A+CaF589k9qepLZZ1Jehnzig7YbD4hEuscGXuBY3fq+g== + version "5.1.1" + resolved "https://registry.npmjs.org/helmet/-/helmet-5.1.1.tgz#609823c5c2e78aea62dd9afc8f544ca409da5e85" + integrity sha512-/yX0oVZBggA9cLJh8aw3PPCfedBnbd7J2aowjzsaWwZh7/UFY0nccn/aHAggIgWUFfnykX8GKd3a1pSbrmlcVQ== hexoid@1.0.0: version "1.0.0" @@ -14912,7 +15360,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -15230,13 +15678,20 @@ is-core-module@^2.1.0, is-core-module@^2.2.0: dependencies: has "^1.0.3" -is-core-module@^2.8.0, is-core-module@^2.8.1, is-core-module@^2.9.0: +is-core-module@^2.8.0, is-core-module@^2.8.1: version "2.9.0" resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== dependencies: has "^1.0.3" +is-core-module@^2.9.0: + version "2.10.0" + resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz#9012ede0a91c69587e647514e1d5277019e728ed" + integrity sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" @@ -15476,13 +15931,6 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-plain-object@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz#47bfc5da1b5d50d64110806c199359482e75a928" - integrity sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg== - dependencies: - isobject "^4.0.0" - is-plain-object@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" @@ -15578,11 +16026,6 @@ is-stream-ended@^0.1.4: resolved "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz#f50224e95e06bce0e356d440a4827cd35b267eda" integrity sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw== -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= - is-stream@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" @@ -15700,6 +16143,11 @@ isarray@2.0.1: resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e" integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4= +isbinaryfile@^4.0.10: + version "4.0.10" + resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" + integrity sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw== + isbinaryfile@^4.0.8: version "4.0.8" resolved "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.8.tgz#5d34b94865bd4946633ecc78a026fc76c5b11fcf" @@ -15727,11 +16175,6 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= -isobject@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" - integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== - isomorphic-dompurify@^0.13.0: version "0.13.0" resolved "https://registry.npmjs.org/isomorphic-dompurify/-/isomorphic-dompurify-0.13.0.tgz#a4dde357e8531018a85ebb2dd56c4794b6739ba3" @@ -15757,9 +16200,9 @@ isomorphic-form-data@^2.0.0: form-data "^2.3.2" isomorphic-git@^1.8.0: - version "1.18.3" - resolved "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.18.3.tgz#b2ef91688ac8f4315a8f3ce72f24a76c17bf61ad" - integrity sha512-CVTNt0uU5RQ4g626LxqUyShdoeD15uZppKA0tk7iY/PyikCbRG594a7BksU4JZcOC6RsqUkURdIlFyKhAfdbqg== + version "1.19.2" + resolved "https://registry.npmjs.org/isomorphic-git/-/isomorphic-git-1.19.2.tgz#e8f57443c63a58054f65f42e5cb189a2df31bd0d" + integrity sha512-14Tbf3GRFNoXw+fy6ssK7gpDZQxF+NytHmg7p+5L38IAVUafHnfjzJ0ZnEmLz3SAG20wYYyB+HufkRAFRttYxQ== dependencies: async-lock "^1.1.0" clean-git-ref "^2.0.1" @@ -15835,6 +16278,11 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +iterall@^1.2.1: + version "1.3.0" + resolved "https://registry.npmjs.org/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" + integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== + iterare@1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz#139c400ff7363690e33abffa33cbba8920f00042" @@ -16349,9 +16797,9 @@ jose@^4.1.4: integrity sha512-GFcVFQwYQKbQTUOo2JlpFGXTkgBw26uzDsRMD2q1WgSKNSnpKS9Ug7bdQ8dS+p4sZHNH6iRPu6WK2jLIjspaMA== jose@^4.6.0: - version "4.8.3" - resolved "https://registry.npmjs.org/jose/-/jose-4.8.3.tgz#5a754fb4aa5f2806608d083f438e6916b11087da" - integrity sha512-7rySkpW78d8LBp4YU70Wb7+OTgE3OwAALNVZxhoIhp4Kscp+p/fBkdpxGAMKxvCAMV4QfXBU9m6l9nX/vGwd2g== + version "4.9.0" + resolved "https://registry.npmjs.org/jose/-/jose-4.9.0.tgz#98ecaf81b13361d1931c0126e3f765549c782f92" + integrity sha512-RgaqEOZLkVO+ViN3KkN44XJt9g7+wMveUv59sVLaTxONcUPc8ZpfqOCeLphVBZyih2dgkvZ0Ap1CNcokvY7Uyw== joycon@^3.0.1: version "3.1.0" @@ -16554,6 +17002,17 @@ json-schema-compare@^0.2.2: dependencies: lodash "^4.17.4" +json-schema-library@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/json-schema-library/-/json-schema-library-7.0.0.tgz#6230a4efba33fe32f9f202298be49c22f981f88f" + integrity sha512-MO3MwDOVhAZU+7k2EZc5Rw5XijdLFZi4T/l7Nhu7HIoopp44JCmCsXD/p73umZhgj3PWhdv3ZqZSukxcvcXhxQ== + dependencies: + deepmerge "^4.2.2" + fast-deep-equal "^3.1.3" + gson-pointer "^4.1.1" + gson-query "^5.1.0" + valid-url "^1.0.9" + json-schema-merge-allof@^0.6.0: version "0.6.0" resolved "https://registry.npmjs.org/json-schema-merge-allof/-/json-schema-merge-allof-0.6.0.tgz#64d48820fec26b228db837475ce3338936bf59a5" @@ -16637,7 +17096,7 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.2, json5@^2.1.3, json5@^2.2.0: +json5@^2.1.2, json5@^2.1.3, json5@^2.2.0, json5@^2.2.1: version "2.2.1" resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== @@ -16818,10 +17277,10 @@ jss@~10.8.2: array-includes "^3.1.2" object.assign "^4.1.2" -jsx-ast-utils@^3.3.1: - version "3.3.1" - resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.1.tgz#a3e0f1cb7e230954eab4dcbce9f6288a78f8ba44" - integrity sha512-pxrjmNpeRw5wwVeWyEAk7QJu2GnBO3uzPFmHCKJJFPKK2Cy0cWL23krGtLdnMmbIi6/FjlrQpPyfQI19ByPOhQ== +jsx-ast-utils@^3.3.2: + version "3.3.2" + resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.2.tgz#afe5efe4332cd3515c065072bd4d6b0aa22152bd" + integrity sha512-4ZCADZHRkno244xlNnn4AOG6sRQ7iBZ5BbgZ4vW4y5IZw7cVUD1PPeblm1xx/nfmMxPdt/LHsXZW8z/j58+l9Q== dependencies: array-includes "^3.1.5" object.assign "^4.1.2" @@ -16941,11 +17400,11 @@ kleur@^4.1.4: integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== knex@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/knex/-/knex-2.1.0.tgz#9348aace3a08ff5be26eb1c8e838416ddf1aa216" - integrity sha512-vVsnD6UJdSJy55TvCXfFF9syfwyXNxfE9mvr2hJL/4Obciy2EPGoqjDpgRSlMruHuPWDOeYAG25nyrGvU+jJog== + version "2.2.0" + resolved "https://registry.npmjs.org/knex/-/knex-2.2.0.tgz#86a3176924d37303b3f9ff7f70087418c263ce7a" + integrity sha512-yhm1Qe9Ok0TeXBq3nNHqZYJPrQ4Iw2tq9k/HxjrZ/EWec2ifOjJlkNHr26v8cQrWtk5iG3iwfUazTIWy+VKG5g== dependencies: - colorette "2.0.16" + colorette "2.0.19" commander "^9.1.0" debug "4.3.4" escalade "^3.1.1" @@ -17039,7 +17498,7 @@ leasot@^12.0.0: strip-ansi "^6.0.0" text-table "^0.2.0" -lerna@^5.0.0: +lerna@~5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/lerna/-/lerna-5.0.0.tgz#077e35d41fcead5ea223af1862dc25475e1aaf2a" integrity sha512-dUYmJ7H9k/xHtwKpQWLTNUa1jnFUiW4o4K2LFkRchlIijoIUT4yK/RprIxNvYCrLrEaOdZryvY5UZvSHI2tBxA== @@ -17156,11 +17615,6 @@ lint-staged@^13.0.0: string-argv "^0.3.1" yaml "^2.1.1" -listenercount@~1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937" - integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc= - listr2@^3.8.3: version "3.14.0" resolved "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz#23101cc62e1375fd5836b248276d1d2b51fdbe9e" @@ -17541,6 +17995,11 @@ long@^4.0.0: resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== +long@^5.0.0: + version "5.2.0" + resolved "https://registry.npmjs.org/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61" + integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w== + longest-streak@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-3.0.0.tgz#f127e2bded83caa6a35ac5f7a2f2b2f94b36f3dc" @@ -17622,7 +18081,7 @@ luxon@^1.23.x: resolved "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf" integrity sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ== -luxon@^2.0.2: +luxon@^2.4.0: version "2.5.0" resolved "https://registry.npmjs.org/luxon/-/luxon-2.5.0.tgz#098090f67d690b247e83c090267a60b1aa8ea96c" integrity sha512-IDkEPB80Rb6gCAU+FEib0t4FeJ4uVOuX1CQ9GsvU3O+JAGIgu0J7sf1OarXKaKDygTZIoJyU6YdZzTFRu+YR0A== @@ -17637,11 +18096,6 @@ lz-string@^1.4.4: resolved "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" integrity sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY= -macos-release@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f" - integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA== - magic-string@^0.25.7: version "0.25.7" resolved "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" @@ -17814,9 +18268,9 @@ markdown-table@^3.0.0: integrity sha512-CBbaYXKSGnE1uLRpKA1SWgIRb2PQrpkllNWpZtZe6VojOJ4ysqiq7/2glYcmKsOYN09QgH/HEBX5hIshAeiK6A== marked@^4.0.14: - version "4.0.18" - resolved "https://registry.npmjs.org/marked/-/marked-4.0.18.tgz#cd0ac54b2e5610cfb90e8fd46ccaa8292c9ed569" - integrity sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw== + version "4.0.19" + resolved "https://registry.npmjs.org/marked/-/marked-4.0.19.tgz#d36198d1ac1255525153c351c68c75bc1d7aee46" + integrity sha512-rgQF/OxOiLcvgUAj1Q1tAf4Bgxn5h5JZTp04Fx4XUkVhs7B+7YA9JEWJhJpoO8eJt8MkZMwqLCNeNqj1bCREZQ== match-sorter@^6.0.2: version "6.3.1" @@ -18455,7 +18909,7 @@ mime@1.6.0, mime@^1.3.4: resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@2.6.0, mime@^2.2.0, mime@^2.5.2: +mime@2.6.0, mime@^2.5.2: version "2.6.0" resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== @@ -18633,6 +19087,13 @@ minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3, minipass@^3. dependencies: yallist "^4.0.0" +minipass@^3.3.5: + version "3.3.5" + resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.5.tgz#6da7e53a48db8a856eeb9153d85b230a2119e819" + integrity sha512-rQ/p+KfKBkeNwo04U15i+hOwoVBVmekmm/HcfTkTN2t9pbQKCMm4eN5gFeqgrrSp/kH/7BYYhTIHOxGqzbBPaA== + dependencies: + yallist "^4.0.0" + minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -18678,7 +19139,7 @@ mkdirp@0.3.0: resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.3.0.tgz#1bbf5ab1ba827af23575143490426455f481fe1e" integrity sha1-G79asbqCevI1dRQ0kEJkVfSB/h4= -"mkdirp@>=0.5 0", mkdirp@^0.5.1: +mkdirp@^0.5.1: version "0.5.5" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -18691,9 +19152,9 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== mock-fs@^5.1.0, mock-fs@^5.1.1: - version "5.1.2" - resolved "https://registry.npmjs.org/mock-fs/-/mock-fs-5.1.2.tgz#6fa486e06d00f8793a8d2228de980eff93ce6db7" - integrity sha512-YkjQkdLulFrz0vD4BfNQdQRVmgycXTV7ykuHMlyv+C8WCHazpkiQRDthwa02kSyo8wKnY9wRptHfQLgmf0eR+A== + version "5.1.4" + resolved "https://registry.npmjs.org/mock-fs/-/mock-fs-5.1.4.tgz#d64dc37b2793613ca7148b510b1167b5b8afb6b8" + integrity sha512-sudhLjCjX37qWIcAlIv1OnAxB2wI4EmXByVuUjILh1rKGNGpGU8GNnzw+EAbrhdpBe0TL/KONbK1y3RXZk8SxQ== modify-values@^1.0.0: version "1.0.1" @@ -18766,10 +19227,10 @@ msw@^0.39.2: type-fest "^1.2.2" yargs "^17.3.1" -msw@^0.44.0: - version "0.44.1" - resolved "https://registry.npmjs.org/msw/-/msw-0.44.1.tgz#0d25d7080b2098bdb84bc5296d0219d0562fe7c2" - integrity sha512-QhTZJQCCv+y4G5l2dLz+2N4K+wWEiz+HfvW6o3ZznDDHbKhQyYmzymU7bWVXXhLbUw7xgxPRxxm1XsYVb6WR7Q== +msw@^0.45.0: + version "0.45.0" + resolved "https://registry.npmjs.org/msw/-/msw-0.45.0.tgz#7bab4ff0a03875aa17b7fefd5fbeea0b71f95957" + integrity sha512-aZgYsSJWYLHj5wZs/g640GP5AK6gfHC6dKTED8bforKZx10IJ+b0z7Y+0infEKD4gNT3orj7tiUZe4pxgpY0SQ== dependencies: "@mswjs/cookies" "^0.2.2" "@mswjs/interceptors" "^0.17.2" @@ -18779,7 +19240,6 @@ msw@^0.44.0: chalk "4.1.1" chokidar "^3.4.2" cookie "^0.4.2" - graphql "^16.3.0" headers-polyfill "^3.0.4" inquirer "^8.2.0" is-node-process "^1.0.1" @@ -18935,11 +19395,6 @@ neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.2: resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - nise@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz#ac4237e0d785ecfcb83e20f389185975da5c31f3" @@ -18997,7 +19452,7 @@ node-fetch@2.6.7, node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1, node- dependencies: whatwg-url "^5.0.0" -node-forge@^1, node-forge@^1.0.0, node-forge@^1.3.1: +node-forge@^1, node-forge@^1.3.1: version "1.3.1" resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== @@ -19062,6 +19517,11 @@ node-releases@^2.0.1: resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + nodemon@^2.0.2: version "2.0.19" resolved "https://registry.npmjs.org/nodemon/-/nodemon-2.0.19.tgz#cac175f74b9cb8b57e770d47841995eebe4488bd" @@ -19277,13 +19737,6 @@ npm-registry-fetch@^9.0.0: minizlib "^2.0.0" npm-package-arg "^8.0.0" -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= - dependencies: - path-key "^2.0.0" - npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -19420,7 +19873,7 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.0, object.assign@^4.1.2: +object.assign@^4.1.0: version "4.1.2" resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== @@ -19430,6 +19883,16 @@ object.assign@^4.1.0, object.assign@^4.1.2: has-symbols "^1.0.1" object-keys "^1.1.1" +object.assign@^4.1.2: + version "4.1.3" + resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.3.tgz#d36b7700ddf0019abb6b1df1bb13f6445f79051f" + integrity sha512-ZFJnX3zltyjcYJL0RoCJuzb+11zWGyaDbjgxZbdV7rFEcHQuYxrZqhow67aA7xpes6LhojyFDaBKAFfogQrikA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + object.entries@^1.1.5: version "1.1.5" resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" @@ -19489,19 +19952,19 @@ octokit-plugin-create-pull-request@^3.10.0: dependencies: "@octokit/types" "^6.8.2" -octokit@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/octokit/-/octokit-2.0.3.tgz#7775a8136be69ef4b6e7f474d50d0d967bd3b74a" - integrity sha512-k9YfQ/0vx1vCAhhmx/8LAvevY5eTRCURqqSkxZCdLVvlX12ke4tp6TxFnKo7/ewIQbrWlFd7KpzOyQCNrOlSRQ== +octokit@^2.0.0, octokit@^2.0.4: + version "2.0.7" + resolved "https://registry.npmjs.org/octokit/-/octokit-2.0.7.tgz#7e6658ddcca234d8cc6ca9344403b516d3b2d136" + integrity sha512-Rf+pY3fCphmS4jjLqQ+D0xS1U+Ry/pAZHLJNvsQksuj4aopl7qFLlV4Id2KIlaUpKZrUCPzOkLiZOaoEb47RZQ== dependencies: "@octokit/app" "^13.0.5" "@octokit/core" "^4.0.4" "@octokit/oauth-app" "^4.0.6" - "@octokit/plugin-paginate-rest" "^3.0.0" + "@octokit/plugin-paginate-rest" "^4.0.0" "@octokit/plugin-rest-endpoint-methods" "^6.0.0" "@octokit/plugin-retry" "^3.0.9" "@octokit/plugin-throttling" "^4.0.1" - "@octokit/types" "^6.35.0" + "@octokit/types" "^7.0.0" oidc-token-hash@^5.0.1: version "5.0.1" @@ -19643,14 +20106,6 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-name@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801" - integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg== - dependencies: - macos-release "^2.2.0" - windows-release "^3.1.0" - os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" @@ -19686,7 +20141,7 @@ p-filter@^2.1.0: p-finally@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== p-is-promise@^3.0.0: version "3.0.0" @@ -20239,11 +20694,6 @@ path-is-inside@1.0.2, path-is-inside@^1.0.2: resolved "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= - path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" @@ -20521,13 +20971,6 @@ pixelmatch@^4.0.2: dependencies: pngjs "^3.0.0" -pkg-dir@4.2.0, pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -20535,6 +20978,13 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + pkg-up@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" @@ -20855,9 +21305,9 @@ postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0, postcss-value-parser@^ integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== postcss@^8.1.0, postcss@^8.4.7: - version "8.4.14" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" - integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== + version "8.4.16" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz#33a1d675fac39941f5f445db0de4db2b6e01d43c" + integrity sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ== dependencies: nanoid "^3.3.4" picocolors "^1.0.0" @@ -20991,11 +21441,6 @@ prismjs@^1.27.0, prismjs@~1.27.0: resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== -private@^0.1.8: - version "0.1.8" - resolved "https://registry.npmjs.org/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - proc-log@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/proc-log/-/proc-log-1.0.0.tgz#0d927307401f69ed79341e83a0b2c9a13395eb77" @@ -21121,13 +21566,6 @@ proto-list@~1.2.1: resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= -proto3-json-serializer@^0.1.8: - version "0.1.9" - resolved "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.9.tgz#705ddb41b009dd3e6fcd8123edd72926abf65a34" - integrity sha512-A60IisqvnuI45qNRygJjrnNjX2TMdQGMY+57tR3nul3ZgO2zXkR9OGR8AXxJhkqx84g0FTnrfi3D5fWMSdANdQ== - dependencies: - protobufjs "^6.11.2" - proto3-json-serializer@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-1.0.0.tgz#4c87b06f5788cb3c9d94be7e0c6ef2420c020146" @@ -21135,7 +21573,7 @@ proto3-json-serializer@^1.0.0: dependencies: protobufjs "^6.11.2" -protobufjs@6.11.3, protobufjs@^6.10.0, protobufjs@^6.11.2, protobufjs@^6.8.6: +protobufjs@6.11.3, protobufjs@^6.10.0, protobufjs@^6.11.2: version "6.11.3" resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== @@ -21154,6 +21592,25 @@ protobufjs@6.11.3, protobufjs@^6.10.0, protobufjs@^6.11.2, protobufjs@^6.8.6: "@types/node" ">=13.7.0" long "^4.0.0" +protobufjs@^7.0.0: + version "7.0.0" + resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-7.0.0.tgz#8c678e1351fd926178fce5a4213913e8d990974f" + integrity sha512-ffNIEm+quOcYtQvHdW406v1NQmZSuqVklxsXk076BtuFnlYZfigLU+JOMrTD8TUOyqHYbRI/fSVNvgd25YeN3w== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^5.0.0" + protocols@^1.1.0, protocols@^1.4.0: version "1.4.7" resolved "https://registry.npmjs.org/protocols/-/protocols-1.4.7.tgz#95f788a4f0e979b291ffefcf5636ad113d037d32" @@ -21224,15 +21681,6 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -pumpify@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz#abfc7b5a621307c728b551decbbefb51f0e4aa1e" - integrity sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw== - dependencies: - duplexify "^4.1.1" - inherits "^2.0.3" - pump "^3.0.0" - punycode@1.3.2: version "1.3.2" resolved "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" @@ -21248,23 +21696,34 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -puppeteer@^15.0.0: - version "15.4.0" - resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-15.4.0.tgz#31f043ee64cc4e1b5cbe99ad900653aab4afb186" - integrity sha512-wxJRbofjaycCaQ9fhABlToJobrjxlABiFi6NvdkOPVJMYFblxDlDTjkg+b6bZYi7xN+lEXn84GBZsA5DYb3wfw== +puppeteer@^16.0.0: + version "16.2.0" + resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-16.2.0.tgz#3fc9cc0c461d3166a98562a7dcd0bf3424a0523c" + integrity sha512-7Au6iC98rS6WEAD110V4Bxd0iIbqoFtzz9XzkG1BSofidS1VAJ881E1+GFR7Xn2Yea0hbj8n0ErzRyseMp1Ctg== dependencies: cross-fetch "3.1.5" debug "4.3.4" - devtools-protocol "0.0.1011705" + devtools-protocol "0.0.1019158" extract-zip "2.0.1" https-proxy-agent "5.0.1" - pkg-dir "4.2.0" progress "2.0.3" proxy-from-env "1.1.0" rimraf "3.0.2" tar-fs "2.1.1" unbzip2-stream "1.4.3" - ws "8.8.0" + ws "8.8.1" + +pvtsutils@^1.3.2: + version "1.3.2" + resolved "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.2.tgz#9f8570d132cdd3c27ab7d51a2799239bf8d8d5de" + integrity sha512-+Ipe2iNUyrZz+8K/2IOo+kKikdtfhRKzNpQbruF2URmqPtoqAs8g3xS7TJvFF2GcPXjh7DkqMnpVveRFq4PgEQ== + dependencies: + tslib "^2.4.0" + +pvutils@^1.1.3: + version "1.1.3" + resolved "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz#f35fc1d27e7cd3dfbd39c0826d173e806a03f5a3" + integrity sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ== q@^1.5.1: version "1.5.1" @@ -21408,15 +21867,6 @@ raw-body@2.5.1, raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" -rc-progress@3.3.3: - version "3.3.3" - resolved "https://registry.npmjs.org/rc-progress/-/rc-progress-3.3.3.tgz#eb9bffbacab1534f2542f9f6861ce772254362b1" - integrity sha512-MDVNVHzGanYtRy2KKraEaWeZLri2ZHWIRyaE1a9MQ2MuJ09m+Wxj5cfcaoaR6z5iRpHpA59YeUxAlpML8N4PJw== - dependencies: - "@babel/runtime" "^7.10.1" - classnames "^2.2.6" - rc-util "^5.16.1" - rc-progress@3.4.0: version "3.4.0" resolved "https://registry.npmjs.org/rc-progress/-/rc-progress-3.4.0.tgz#80a33c25c9675f5836ba25a87cd8dc310aad72b1" @@ -21474,13 +21924,13 @@ react-copy-to-clipboard@^5.0.4: copy-to-clipboard "^3.3.1" prop-types "^15.8.1" -react-debounce-input@=3.2.4: - version "3.2.4" - resolved "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.2.4.tgz#8204373a6498776536a2fcc7e467d054c3b729d4" - integrity sha512-fX70bNj0fLEYO2Zcvuh7eh9wOUQ29GIx6r8IxIJlc0i0mpUH++9ax0BhfAYfzndADli3RAMROrZQ014J01owrg== +react-debounce-input@=3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/react-debounce-input/-/react-debounce-input-3.3.0.tgz#85e3ebcaa41f2016e50613134a1ec9fe3cdb422e" + integrity sha512-VEqkvs8JvY/IIZvh71Z0TC+mdbxERvYF33RcebnodlsUZ8RSgyKe2VWaHXv4+/8aoOgXLxWrdsYs2hDhcwbUgA== dependencies: lodash.debounce "^4" - prop-types "^15.7.2" + prop-types "^15.8.1" react-dev-utils@^12.0.0-next.60: version "12.0.1" @@ -21587,6 +22037,11 @@ react-hot-loader@^4.13.0: shallowequal "^1.1.0" source-map "^0.7.3" +react-icons@^4.4.0: + version "4.4.0" + resolved "https://registry.npmjs.org/react-icons/-/react-icons-4.4.0.tgz#a13a8a20c254854e1ec9aecef28a95cdf24ef703" + integrity sha512-fSbvHeVYo/B5/L4VhB7sBA1i2tS8MkT0Hb9t2H1AVPkwGfVHLJCqyr2Py9dKMxsyM63Eng1GkdZfbWj+Fmv8Rg== + react-immutable-proptypes@2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/react-immutable-proptypes/-/react-immutable-proptypes-2.2.0.tgz#cce96d68cc3c18e89617cbf3092d08e35126af4a" @@ -21795,7 +22250,7 @@ react-universal-interface@^0.6.2: resolved "https://registry.npmjs.org/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b" integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw== -react-use@^17.2.4, react-use@^17.3.1, react-use@^17.3.2: +react-use@^17.2.4, react-use@^17.3.1, react-use@^17.3.2, react-use@^17.4.0: version "17.4.0" resolved "https://registry.npmjs.org/react-use/-/react-use-17.4.0.tgz#cefef258b0a6c534a5c8021c2528ac6e1a4cdc6d" integrity sha512-TgbNTCA33Wl7xzIJegn1HndB4qTS9u03QUwyNycUnXaweZkE4Kq2SB+Yoxx8qbshkZGYBDvUXbXWRUmQDcZZ/Q== @@ -22137,6 +22592,13 @@ refractor@^3.6.0: parse-entities "^2.0.0" prismjs "~1.27.0" +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties@^8.2.0: version "8.2.0" resolved "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" @@ -22149,6 +22611,11 @@ regenerate@^1.4.0: resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== +regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + regenerator-runtime@^0.10.5: version "0.10.5" resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" @@ -22164,13 +22631,12 @@ regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4: resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== -regenerator-transform@^0.14.2: - version "0.14.4" - resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7" - integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw== +regenerator-transform@^0.15.0: + version "0.15.0" + resolved "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" + integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== dependencies: "@babel/runtime" "^7.8.4" - private "^0.1.8" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" @@ -22206,11 +22672,28 @@ regexpu-core@^4.7.1: unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.2.0" +regexpu-core@^5.1.0: + version "5.1.0" + resolved "https://registry.npmjs.org/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d" + integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + regjsgen@^0.5.1: version "0.5.1" resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.1.tgz#48f0bf1a5ea205196929c0d9798b42d1ed98443c" integrity sha512-5qxzGZjDs9w4tzT3TPhCJqWdCc3RLYwy9J2NB0nm5Lz+S273lvWcpjaTGHsT1dc6Hhfq41uSEOw8wBmxrKOuyg== +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.npmjs.org/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== + regjsparser@^0.6.4: version "0.6.4" resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" @@ -22218,6 +22701,13 @@ regjsparser@^0.6.4: dependencies: jsesc "~0.5.0" +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== + dependencies: + jsesc "~0.5.0" + regression@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/regression/-/regression-2.0.1.tgz#8d29c3e8224a10850c35e337e85a8b2fac3b0c87" @@ -22329,11 +22819,6 @@ replace-in-file@^6.0.0: glob "^7.2.0" yargs "^17.2.1" -replaceall@^0.1.6: - version "0.1.6" - resolved "https://registry.npmjs.org/replaceall/-/replaceall-0.1.6.tgz#81d81ac7aeb72d7f5c4942adf2697a3220688d8e" - integrity sha1-gdgax663LX9cSUKt8ml6MiBojY4= - request-progress@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" @@ -22509,14 +22994,6 @@ ret@~0.1.10: resolved "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry-request@^4.0.0: - version "4.2.2" - resolved "https://registry.npmjs.org/retry-request/-/retry-request-4.2.2.tgz#b7d82210b6d2651ed249ba3497f07ea602f1a903" - integrity sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg== - dependencies: - debug "^4.1.1" - extend "^3.0.2" - retry-request@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/retry-request/-/retry-request-5.0.0.tgz#886ff8ec0e77fffbe66a4d5e90fd8f6646b6eae4" @@ -22557,13 +23034,6 @@ rifm@^0.7.0: dependencies: "@babel/runtime" "^7.3.1" -rimraf@2, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" @@ -22571,6 +23041,13 @@ rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@~2.6.2: version "2.6.3" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -22608,9 +23085,9 @@ rollup-plugin-dts@^4.0.1: "@babel/code-frame" "^7.16.7" rollup-plugin-esbuild@^4.7.2: - version "4.9.1" - resolved "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-4.9.1.tgz#369d137e2b1542c8ee459495fd4f10de812666aa" - integrity sha512-qn/x7Wz9p3Xnva99qcb+nopH0d2VJwVnsxJTGEg+Sh2Z3tqQl33MhOwzekVo1YTKgv+yAmosjcBRJygMfGrtLw== + version "4.9.3" + resolved "https://registry.npmjs.org/rollup-plugin-esbuild/-/rollup-plugin-esbuild-4.9.3.tgz#8c62042bdda9f33d18b1c280914394e5a842dd53" + integrity sha512-bxfUNYTa9Tw/4kdFfT9gtidDtqXyRdCW11ctZM7D8houCCVqp5qHzQF7hhIr31rqMA0APbG47fgVbbCGXgM49Q== dependencies: "@rollup/pluginutils" "^4.1.1" debug "^4.3.3" @@ -22672,9 +23149,9 @@ rollup@^0.63.4: "@types/node" "*" rollup@^2.60.2: - version "2.77.0" - resolved "https://registry.npmjs.org/rollup/-/rollup-2.77.0.tgz#749eaa5ac09b6baa52acc076bc46613eddfd53f4" - integrity sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g== + version "2.77.3" + resolved "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz#8f00418d3a2740036e15deb653bed1a90ee0cc12" + integrity sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g== optionalDependencies: fsevents "~2.3.2" @@ -22702,7 +23179,7 @@ run-script-webpack-plugin@^0.1.0: resolved "https://registry.npmjs.org/run-script-webpack-plugin/-/run-script-webpack-plugin-0.1.1.tgz#dad3114be32eb864d2160306e4d9c52a2c1cfd59" integrity sha512-PrxBRLv1K9itDKMlootSCyGhdTU+KbKGJ2wF6/k0eyo6M0YGPC58HYbS/J/QsDiwM0t7G99WcuCqto0J7omOXA== -rxjs@7.5.5, rxjs@^7.0.0, rxjs@^7.1.0, rxjs@^7.2.0, rxjs@^7.5.1, rxjs@^7.5.5: +rxjs@7.5.5, rxjs@^7.1.0, rxjs@^7.5.1, rxjs@^7.5.5: version "7.5.5" resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw== @@ -22716,6 +23193,13 @@ rxjs@^6.6.0, rxjs@^6.6.3: dependencies: tslib "^1.9.0" +rxjs@^7.0.0: + version "7.5.6" + resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.5.6.tgz#0446577557862afd6903517ce7cae79ecb9662bc" + integrity sha512-dnyv2/YsXhnm461G+R/Pe5bWP41Nm6LBXEYWI6eiFP4fiwx6WRI/CD0zbdVAudd9xwLEF2IDcKXLHit0FYjUzw== + dependencies: + tslib "^2.1.0" + sade@^1.7.3: version "1.8.1" resolved "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701" @@ -22872,7 +23356,7 @@ semver-store@^0.3.0: resolved "https://registry.npmjs.org/semver-store/-/semver-store-0.3.0.tgz#ce602ff07df37080ec9f4fb40b29576547befbe9" integrity sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg== -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: +"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.6.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -23018,7 +23502,7 @@ set-value@^4.1.0: is-plain-object "^2.0.4" is-primitive "^3.0.1" -setimmediate@^1.0.4, setimmediate@^1.0.5, setimmediate@~1.0.4: +setimmediate@^1.0.4, setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= @@ -23402,14 +23886,6 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-resolve@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" - integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - source-map-support@^0.5.10, source-map-support@^0.5.16, source-map-support@^0.5.17, source-map-support@^0.5.6, source-map-support@~0.5.20: version "0.5.21" resolved "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" @@ -23438,7 +23914,7 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3, source-map@~0.7.2: +source-map@^0.7.3: version "0.7.3" resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== @@ -23735,7 +24211,7 @@ stream-combiner@~0.0.4: dependencies: duplexer "~0.1.1" -stream-events@^1.0.4, stream-events@^1.0.5: +stream-events@^1.0.5: version "1.0.5" resolved "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz#bbc898ec4df33a4902d892333d47da9bf1c406d5" integrity sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg== @@ -23945,11 +24421,6 @@ strip-bom@^4.0.0: resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= - strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" @@ -24050,10 +24521,21 @@ stylis@^4.0.6: resolved "https://registry.npmjs.org/stylis/-/stylis-4.0.7.tgz#412a90c28079417f3d27c028035095e4232d2904" integrity sha512-OFFeUXFgwnGOKvEXaSv0D0KQ5ADP0n6g3SVONx6I/85JzNZ3u50FRwB3lVIk1QO2HNdI75tbVzc4Z66Gdp9voA== +subscriptions-transport-ws@^0.11.0: + version "0.11.0" + resolved "https://registry.npmjs.org/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.0.tgz#baf88f050cba51d52afe781de5e81b3c31f89883" + integrity sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ== + dependencies: + backo2 "^1.0.2" + eventemitter3 "^3.1.0" + iterall "^1.2.1" + symbol-observable "^1.0.4" + ws "^5.2.0 || ^6.0.0 || ^7.0.0" + sucrase@^3.18.0, sucrase@^3.20.2: - version "3.24.0" - resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.24.0.tgz#66a8f2cc845bc441706ce5f3056de283289067b6" - integrity sha512-SevqflhW356TKEyWjFHg2e5f3eH+5rzmsMJxrVMDvZIEHh/goYrpzDGA6APEj4ME9MdGm8oNgIzi1eF3c3dDQA== + version "3.25.0" + resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.25.0.tgz#6dffa34e614b3347877507a4380cc4f022b7b7aa" + integrity sha512-WxTtwEYXSmZArPGStGBicyRsg5TBEFhT5b7N+tF+zauImP0Acy+CoUK0/byJ8JNPK/5lbpWIVuFagI4+0l85QQ== dependencies: commander "^4.0.0" glob "7.1.6" @@ -24079,7 +24561,7 @@ superagent@^8.0.0: readable-stream "^3.6.0" semver "^7.3.7" -supertest@^6.1.3, supertest@^6.1.6: +supertest@^6.1.3, supertest@^6.1.6, supertest@^6.2.4: version "6.2.4" resolved "https://registry.npmjs.org/supertest/-/supertest-6.2.4.tgz#3dcebe42f7fd6f28dd7ac74c6cba881f7101b2f0" integrity sha512-M8xVnCNv+q2T2WXVzxDECvL2695Uv2uUj2O0utxsld/HRyJvOU8W9f1gvsYxSNU4wmIe0/L/ItnpU4iKq0emDA== @@ -24121,12 +24603,12 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== -svg-parser@^2.0.2: +svg-parser@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== -svgo@^2.5.0, svgo@^2.7.0: +svgo@^2.7.0, svgo@^2.8.0: version "2.8.0" resolved "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== @@ -24159,17 +24641,17 @@ swagger-client@^3.18.5: url "~0.11.0" swagger-ui-react@^4.11.1: - version "4.12.0" - resolved "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-4.12.0.tgz#bfdf67bd0679fdd62ec3fb98bd827afb81fb7fe6" - integrity sha512-pkSkUe4WVb7omoScK8GG2qgD6LxwZEIA+fKcxeACC7PCW52vFEjle6WO6lFOLj1JmfWriL7Ngi0+wJtVjfhnWw== + version "4.14.0" + resolved "https://registry.npmjs.org/swagger-ui-react/-/swagger-ui-react-4.14.0.tgz#c1a26955d8481ad024eada6e1d59c44d0b061ab1" + integrity sha512-Yz3E5a5ujj2jqI4V+OELUjgs04uGNkJxbFLTe9KyrSs37yeMsyoDwLRGWuAAP6BRLhonJzLeZRTbnD2cK+iVew== dependencies: - "@babel/runtime-corejs3" "^7.16.8" + "@babel/runtime-corejs3" "^7.18.9" "@braintree/sanitize-url" "=6.0.0" base64-js "^1.5.1" classnames "^2.3.1" css.escape "1.5.1" deep-extend "0.6.0" - dompurify "=2.3.3" + dompurify "=2.3.10" ieee754 "^1.2.1" immutable "^3.x.x" js-file-download "^0.4.12" @@ -24179,7 +24661,7 @@ swagger-ui-react@^4.11.1: randexp "^0.5.3" randombytes "^2.1.0" react-copy-to-clipboard "5.0.4" - react-debounce-input "=3.2.4" + react-debounce-input "=3.3.0" react-immutable-proptypes "2.2.0" react-immutable-pure-component "^2.2.0" react-inspector "^5.1.1" @@ -24209,7 +24691,7 @@ swr@^1.1.2: resolved "https://registry.npmjs.org/swr/-/swr-1.3.0.tgz#c6531866a35b4db37b38b72c45a63171faf9f4e8" integrity sha512-dkghQrOl2ORX9HYrMDtPa7LTVHJjCTeZoB1dqTbnnEDlSvN8JEKpYIYurDfvbQFUUS8Cg8PceFVZNkW0KNNYPw== -symbol-observable@1.2.0: +symbol-observable@1.2.0, symbol-observable@^1.0.4: version "1.2.0" resolved "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== @@ -24219,7 +24701,7 @@ symbol-tree@^3.2.4: resolved "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -sync-fetch@0.4.1, sync-fetch@^0.4.0: +sync-fetch@^0.4.0: version "0.4.1" resolved "https://registry.npmjs.org/sync-fetch/-/sync-fetch-0.4.1.tgz#87b8684eef2fa25c96c4683ae308473a4e5c571f" integrity sha512-JDtyFEvnKUzt1CxRtzzsGgkBanEv8XRmLyJo0F0nGkpCR8EjYmpOJJXz8GA/SWtlPU0nAYh0+CNMNnFworGyOA== @@ -24293,21 +24775,21 @@ tdigest@^0.1.1: bintrees "1.0.1" "techdocs-cli-embedded-app@link:packages/techdocs-cli-embedded-app": - version "0.2.72-next.3" + version "0.2.73" dependencies: - "@backstage/app-defaults" "^1.0.4-next.3" - "@backstage/catalog-model" "^1.1.0-next.3" - "@backstage/cli" "^0.18.0-next.3" + "@backstage/app-defaults" "^1.0.5" + "@backstage/catalog-model" "^1.1.0" + "@backstage/cli" "^0.18.1" "@backstage/config" "^1.0.1" - "@backstage/core-app-api" "^1.0.4-next.1" - "@backstage/core-components" "^0.10.0-next.3" - "@backstage/core-plugin-api" "^1.0.4-next.0" - "@backstage/integration-react" "^1.1.2-next.3" - "@backstage/plugin-catalog" "^1.4.0-next.3" - "@backstage/plugin-techdocs" "^1.2.1-next.3" - "@backstage/plugin-techdocs-react" "^1.0.2-next.2" - "@backstage/test-utils" "^1.1.2-next.2" - "@backstage/theme" "^0.2.16-next.1" + "@backstage/core-app-api" "^1.0.5" + "@backstage/core-components" "^0.11.0" + "@backstage/core-plugin-api" "^1.0.5" + "@backstage/integration-react" "^1.1.3" + "@backstage/plugin-catalog" "^1.5.0" + "@backstage/plugin-techdocs" "^1.3.1" + "@backstage/plugin-techdocs-react" "^1.0.3" + "@backstage/test-utils" "^1.1.3" + "@backstage/theme" "^0.2.16" "@material-ui/core" "^4.11.0" "@material-ui/icons" "^4.9.1" history "^5.0.0" @@ -24354,24 +24836,24 @@ terminal-link@^2.0.0: supports-hyperlinks "^2.0.0" terser-webpack-plugin@*, terser-webpack-plugin@^5.1.3: - version "5.3.3" - resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz#8033db876dd5875487213e87c627bca323e5ed90" - integrity sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ== + version "5.3.5" + resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.5.tgz#f7d82286031f915a4f8fb81af4bd35d2e3c011bc" + integrity sha512-AOEDLDxD2zylUGf/wxHxklEkOe2/r+seuyOWujejFrIxHf11brA1/dWQNIgXa1c6/Wkxgu7zvv0JhOWfc2ELEA== dependencies: - "@jridgewell/trace-mapping" "^0.3.7" + "@jridgewell/trace-mapping" "^0.3.14" jest-worker "^27.4.5" schema-utils "^3.1.1" serialize-javascript "^6.0.0" - terser "^5.7.2" + terser "^5.14.1" -terser@^5.10.0, terser@^5.7.2: - version "5.12.0" - resolved "https://registry.npmjs.org/terser/-/terser-5.12.0.tgz#728c6bff05f7d1dcb687d8eace0644802a9dae8a" - integrity sha512-R3AUhNBGWiFc77HXag+1fXpAxTAFRQTJemlJKjAgD9r8xXTpjNKqIXwHM/o7Rh+O0kUJtS3WQVdBeMKFk5sw9A== +terser@^5.10.0, terser@^5.14.1: + version "5.14.2" + resolved "https://registry.npmjs.org/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== dependencies: + "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" commander "^2.20.0" - source-map "~0.7.2" source-map-support "~0.5.20" test-exclude@^6.0.0: @@ -24384,9 +24866,9 @@ test-exclude@^6.0.0: minimatch "^3.0.4" testcontainers@^8.1.2: - version "8.11.1" - resolved "https://registry.npmjs.org/testcontainers/-/testcontainers-8.11.1.tgz#07d46e9da461e03d613c094570edf43506040082" - integrity sha512-sJbc/JiQ509mphYhj79pEpRb6iUePX7MY+YLi3gzSONoSgwPRgtqDMM2UBVjEBI123zavwN9K/HGUXwIIDah4A== + version "8.12.0" + resolved "https://registry.npmjs.org/testcontainers/-/testcontainers-8.12.0.tgz#236dfaec40887348d28bfcd19ebd047eb32f712a" + integrity sha512-6qQqKirdURAXH/V6sVnfbgqLAJK/vxP2ED6qcwiLfsZ6McPkF5TGDAPzkVZUmdrx62H3RzuTTdXGoPcLP7KG6g== dependencies: "@balena/dockerignore" "^1.0.2" "@types/archiver" "^5.3.1" @@ -24664,12 +25146,7 @@ tr46@^2.1.0: tr46@~0.0.3: version "0.0.3" resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= - -"traverse@>=0.3.0 <0.4": - version "0.3.9" - resolved "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" - integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk= + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== traverse@^0.6.6, traverse@~0.6.6: version "0.6.6" @@ -25031,11 +25508,21 @@ undici@5.5.1: resolved "https://registry.npmjs.org/undici/-/undici-5.5.1.tgz#baaf25844a99eaa0b22e1ef8d205bffe587c8f43" integrity sha512-MEvryPLf18HvlCbLSzCW0U00IMftKGI5udnjrQbC5D4P0Hodwffhv+iGfWuJwg16Y/TK11ZFK8i+BPVW2z/eAw== +undici@^5.8.0: + version "5.8.0" + resolved "https://registry.npmjs.org/undici/-/undici-5.8.0.tgz#dec9a8ccd90e5a1d81d43c0eab6503146d649a4f" + integrity sha512-1F7Vtcez5w/LwH2G2tGnFIihuWUlc58YidwLiCv+jR2Z50x0tNXpRRw7eOIJ+GvqCqIkg9SB7NWAJ/T9TLfv8Q== + unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== +unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + unicode-match-property-ecmascript@^1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" @@ -25044,16 +25531,34 @@ unicode-match-property-ecmascript@^1.0.4: unicode-canonical-property-names-ecmascript "^1.0.4" unicode-property-aliases-ecmascript "^1.0.4" +unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript@^1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== +unicode-match-property-value-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" + integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== + unicode-property-aliases-ecmascript@^1.0.4: version "1.1.0" resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz#dd57a99f6207bedff4628abefb94c50db941c8f4" integrity sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg== +unicode-property-aliases-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" + integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== + unidiff@1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/unidiff/-/unidiff-1.0.2.tgz#8706eb36e4aa182a6ca699ecd2f8877f4b906ce0" @@ -25174,13 +25679,6 @@ universal-github-app-jwt@^1.0.1: "@types/jsonwebtoken" "^8.3.3" jsonwebtoken "^8.5.1" -universal-user-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-5.0.0.tgz#a3182aa758069bf0e79952570ca757de3579c1d9" - integrity sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q== - dependencies: - os-name "^3.1.0" - universal-user-agent@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" @@ -25229,27 +25727,19 @@ untildify@^4.0.0: resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== -unzipper@^0.10.11: - version "0.10.11" - resolved "https://registry.npmjs.org/unzipper/-/unzipper-0.10.11.tgz#0b4991446472cbdb92ee7403909f26c2419c782e" - integrity sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw== - dependencies: - big-integer "^1.6.17" - binary "~0.3.0" - bluebird "~3.4.1" - buffer-indexof-polyfill "~1.0.0" - duplexer2 "~0.1.4" - fstream "^1.0.12" - graceful-fs "^4.2.2" - listenercount "~1.0.1" - readable-stream "~2.3.6" - setimmediate "~1.0.4" - upath@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== +update-browserslist-db@^1.0.4: + version "1.0.5" + resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + upper-case-first@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz#992c3273f882abd19d1e02894cc147117f844324" @@ -25305,6 +25795,14 @@ url@^0.11.0, url@~0.11.0: punycode "1.3.2" querystring "0.2.0" +use-deep-compare-effect@^1.8.1: + version "1.8.1" + resolved "https://registry.npmjs.org/use-deep-compare-effect/-/use-deep-compare-effect-1.8.1.tgz#ef0ce3b3271edb801da1ec23bf0754ef4189d0c6" + integrity sha512-kbeNVZ9Zkc0RFGpfMN3MNfaKNvcLNyxOAAd9O4CBZ+kCBXXscn9s/4I+8ytUER4RDpEYs5+O6Rs4PqiZ+rHr5Q== + dependencies: + "@babel/runtime" "^7.12.5" + dequal "^2.0.2" + use-immer@^0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/use-immer/-/use-immer-0.7.0.tgz#e3bfbb806b5e3ff6e37441be74c306d91c1e0962" @@ -25424,6 +25922,11 @@ v8-to-istanbul@^8.1.0: convert-source-map "^1.6.0" source-map "^0.7.3" +valid-url@^1.0.9: + version "1.0.9" + resolved "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" + integrity sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA== + validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -25613,7 +26116,7 @@ walker@^1.0.7: dependencies: makeerror "1.0.x" -watchpack@^2.0.0-beta.10: +watchpack@^2.0.0-beta.10, watchpack@^2.4.0: version "2.4.0" resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== @@ -25621,14 +26124,6 @@ watchpack@^2.0.0-beta.10: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -watchpack@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" - integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - wbuf@^1.1.0, wbuf@^1.7.3: version "1.7.3" resolved "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" @@ -25662,10 +26157,21 @@ web-streams-polyfill@^3.2.0: resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.0.tgz#a6b74026b38e4885869fb5c589e90b95ccfc7965" integrity sha512-EqPmREeOzttaLRm5HS7io98goBgZ7IVz79aDvqjD0kYXLtFZTc0T/U6wHTPKyIjb+MdN7DFIIX6hgdBEpWmfPA== +webcrypto-core@^1.7.4: + version "1.7.5" + resolved "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.5.tgz#c02104c953ca7107557f9c165d194c6316587ca4" + integrity sha512-gaExY2/3EHQlRNNNVSrbG2Cg94Rutl7fAaKILS1w8ZDhGxdFOaw6EbCfHIxPy9vt/xwp5o0VQAx9aySPF6hU1A== + dependencies: + "@peculiar/asn1-schema" "^2.1.6" + "@peculiar/json-schema" "^1.1.12" + asn1js "^3.0.1" + pvtsutils "^1.3.2" + tslib "^2.4.0" + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== webidl-conversions@^5.0.0: version "5.0.0" @@ -25689,9 +26195,9 @@ webpack-dev-middleware@^5.3.1: schema-utils "^4.0.0" webpack-dev-server@^4.7.3: - version "4.9.3" - resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.3.tgz#2360a5d6d532acb5410a668417ad549ee3b8a3c9" - integrity sha512-3qp/eoboZG5/6QgiZ3llN8TUzkSpYg1Ko9khWX1h40MIEUNS2mDoIa8aXsPfskER+GbTvs/IJZ1QTBBhhuetSw== + version "4.10.0" + resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.10.0.tgz#de270d0009eba050546912be90116e7fd740a9ca" + integrity sha512-7dezwAs+k6yXVFZ+MaL8VnE+APobiO3zvpp3rBHe/HmWQ+avwh0Q3d0xxacOiBybZZ3syTZw9HXzpa3YNbAZDQ== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" @@ -25742,20 +26248,20 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5, webpack@^5.66.0: - version "5.73.0" - resolved "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz#bbd17738f8a53ee5760ea2f59dce7f3431d35d38" - integrity sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA== + version "5.74.0" + resolved "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" + integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^0.0.51" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.4.1" + acorn "^8.7.1" acorn-import-assertions "^1.7.6" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.9.3" + enhanced-resolve "^5.10.0" es-module-lexer "^0.9.0" eslint-scope "5.1.1" events "^3.2.0" @@ -25768,7 +26274,7 @@ webpack@^5, webpack@^5.66.0: schema-utils "^3.1.0" tapable "^2.1.1" terser-webpack-plugin "^5.1.3" - watchpack "^2.3.1" + watchpack "^2.4.0" webpack-sources "^3.2.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: @@ -25810,7 +26316,7 @@ whatwg-mimetype@^3.0.0: whatwg-url@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== dependencies: tr46 "~0.0.3" webidl-conversions "^3.0.0" @@ -25892,13 +26398,6 @@ window-size@^0.2.0: resolved "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= -windows-release@^3.1.0: - version "3.2.0" - resolved "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f" - integrity sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA== - dependencies: - execa "^1.0.0" - winston-transport@^4.5.0: version "4.5.0" resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa" @@ -25908,7 +26407,7 @@ winston-transport@^4.5.0: readable-stream "^3.6.0" triple-beam "^1.3.0" -winston@^3.2.1, winston@^3.7.2: +winston@^3.2.1, winston@^3.7.2, winston@^3.8.1: version "3.8.1" resolved "https://registry.npmjs.org/winston/-/winston-3.8.1.tgz#76f15b3478cde170b780234e0c4cf805c5a7fb57" integrity sha512-r+6YAiCR4uI3N8eQNOg8k3P3PqwAm20cLKlzVD9E66Ch39+LZC+VH1UKf9JemQj2B3QoUHfKD7Poewn0Pr3Y1w== @@ -25963,7 +26462,7 @@ wrap-ansi@^7.0.0: wrappy@1: version "1.0.2" resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== write-file-atomic@^2.3.0, write-file-atomic@^2.4.2: version "2.4.3" @@ -26025,21 +26524,21 @@ write-pkg@^4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" -ws@8.8.0: - version "8.8.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769" - integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ== +ws@8.8.1, ws@^8.3.0: + version "8.8.1" + resolved "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" + integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== + +"ws@^5.2.0 || ^6.0.0 || ^7.0.0": + version "7.5.9" + resolved "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== ws@^7.3.1, ws@^7.4.6: version "7.5.7" resolved "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== -ws@^8.0.0, ws@^8.3.0: - version "8.8.1" - resolved "https://registry.npmjs.org/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" - integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== - ws@^8.4.2: version "8.5.0" resolved "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" @@ -26227,9 +26726,9 @@ yargs-parser@^20.2.2: integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== yargs-parser@^21.0.0: - version "21.0.1" - resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz#0267f286c877a4f0f728fceb6f8a3e4cb95c6e35" - integrity sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg== + version "21.1.1" + resolved "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== yargs-parser@^3.2.0: version "3.2.0" @@ -26327,7 +26826,7 @@ yarn-lock-check@^1.0.5: yauzl@^2.10.0: version "2.10.0" resolved "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" - integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= + integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g== dependencies: buffer-crc32 "~0.2.3" fd-slicer "~1.1.0" @@ -26338,9 +26837,9 @@ yeast@0.1.2: integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= yeoman-environment@^3.9.1: - version "3.9.1" - resolved "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-3.9.1.tgz#21912bdee4b1d302a5c25a7d31338fa092ea7116" - integrity sha512-IdRnbQt/DSOSnao0oD9c+or1X2UrL+fx9eC0O7Lq/MGZV68nhv9k77MqG+hEAySPSlyCpocVlhfQwV62hczk5Q== + version "3.10.0" + resolved "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-3.10.0.tgz#d8c56571b68d16b4af8abfb950f83acc503eed77" + integrity sha512-sYtSxBK9daq21QjoskJTHKLQ1xEsRPURkmFV/aM8HS8ZlQVzwx57Rz1zCs8EGPhK4vqsmTE8H92Gp1jg1fT3EA== dependencies: "@npmcli/arborist" "^4.0.4" are-we-there-yet "^2.0.0" @@ -26360,6 +26859,7 @@ yeoman-environment@^3.9.1: grouped-queue "^2.0.0" inquirer "^8.0.0" is-scoped "^2.1.0" + isbinaryfile "^4.0.10" lodash "^4.17.10" log-symbols "^4.0.0" mem-fs "^1.2.0 || ^2.0.0" @@ -26455,9 +26955,9 @@ zip-stream@^4.1.0: readable-stream "^3.6.0" zod@^3.11.6, zod@^3.9.5: - version "3.17.3" - resolved "https://registry.npmjs.org/zod/-/zod-3.17.3.tgz#86abbc670ff0063a4588d85a4dcc917d6e4af2ba" - integrity sha512-4oKP5zvG6GGbMlqBkI5FESOAweldEhSOZ6LI6cG+JzUT7ofj1ZOC0PJudpQOpT1iqOFpYYtX5Pw0+o403y4bcg== + version "3.18.0" + resolved "https://registry.npmjs.org/zod/-/zod-3.18.0.tgz#2eed58b3cafb8d9a67aa2fee69279702f584f3bc" + integrity sha512-gwTm8RfUCe8l9rDwN5r2A17DkAa8Ez4Yl4yXqc5VqeGaXaJahzYYXbTwvhroZi0SNBqTwh/bKm2N0mpCzuw4bA== zustand@3.6.9: version "3.6.9"